【问题标题】:Observing AngularJS observables观察 AngularJS 可观察对象
【发布时间】:2013-07-04 21:59:47
【问题描述】:

使用 AngularJS,我应该如何触发模型现在是脏的并且需要保存到服务器?除了用户点击“保存”按钮之外?

我曾想过使用 $watch,但是当第一次加载数据时它会触发,所以你最终会得到这个 hack:

How do I ignore the initial load when watching model changes in AngularJS?

您也可以通过 $emit 事件触发保存,但是当您:

  1. 在范围上设置属性
  2. $在该范围内发出一个事件
  3. 在父控制器中使用 $on 捕获事件并查看属性

按此顺序,在步骤 3 中声明的事件处理程序将看到在步骤 1 中进行更改之前的范围属性。

我在这里整理了一个例子:

http://plnkr.co/edit/Il9TzUdCSBdewCxIKARZ

如果您单击 foo,然后单击 bar,然后单击 foo,然后单击 bar,您将看到事件侦听器始终落后于属性一步。

我假设这与处理与摘要周期相关的范围事件有关,但它似乎确实违反了 javascript 的法律。 Angular 的人是怎么做到的,所以当你改变它时,它的属性不会改变!?

当我总是保存旧数据时,这让我有些头疼。

快速解决方法是使用 $timeout 来“推迟”保存,我假设直到摘要周期结束。虽然这有效,但它看起来很混乱。这里发生了什么?如果对范围的更改对事件处理程序不可见,那么事件似乎毫无用处,不是吗?

有没有一种干净的方法可以做到这一点?

谢谢。

【问题讨论】:

    标签: javascript angularjs angularjs-scope


    【解决方案1】:

    这是因为双向绑定直到 $digest 循环才会更新,这发生在您的 $emit 之后。

    我建议在数据上使用$watch 来触发保存。

    // Controller
    $scope.$watch('message', function(newVal, oldVal) {
      if (newVal === oldVal) {
        return;
      }
      // Handle update...
    });
    

    另一种选择是将对象而不是字符串传递给指令。通过这样做,$on 侦听器将可以访问正确的数据。

    例如:

    // Controller
    $scope.messageData = {message: "Initial message"};
    
    // HTML
    <div set-message="messageData">...</div>
    
    // Directive
    scope: {
      messageData: "=setMessage"
    },
    link: function(scope) {
      scope.setMessage = function(message) {
        scope.messageData.message = message;
        scope.$emit('messagechange');
      };
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-17
      • 1970-01-01
      • 2019-09-09
      • 1970-01-01
      • 2023-04-02
      • 2012-04-20
      • 2019-01-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多