3

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

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

在 AngularJS 中观看模型更改时如何忽略初始负载?

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

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

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

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

http://plnkr.co/edit/Il9TzUdCSBdewCxIKARZ

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

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

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

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

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

谢谢。

4

1 回答 1

1

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

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

// 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');
  };
}
于 2013-07-05T13:51:09.433 回答