观察AngularJS可观察量

时间:2013-07-04 21:59:48

标签: javascript angularjs angularjs-scope

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

我想过使用$ watch,但是当数据首次加载时会触发,所以你最终会遇到这个黑客:

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

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

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

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

    我在这里举了一个例子:

    http://plnkr.co/edit/Il9TzUdCSBdewCxIKARZ

    如果单击foo,然后选择bar,然后选择foo,然后选择bar,您将看到事件监听器始终位于属性后面一步。

    我认为这与处理与摘要周期相关的范围事件有关,但它似乎违反了javascript法则。 Angular家伙是如何设法做到的,所以当你改变它时财产不会改变!?

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

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

    这样做有干净的方法吗?

    感谢。

1 个答案:

答案 0 :(得分: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');
  };
}