【问题标题】:How to ignore Angular $watch event when I myself have caused it?当我自己引起Angular $watch 事件时,如何忽略它?
【发布时间】:2015-11-26 00:55:27
【问题描述】:

我有一个带有 ngModel 链接的自定义 UI 元素:

scope: 
{   
  ngModel        : "="
}

附加模型可能有两种变化方式:

  1. 它是从外部更改的 - 在这种情况下,我想更新我的自定义元素的 UI
  2. 它是从内部更改的 - 在这种情况下,我想忽略更改,因为我的 UI 已经是最新的

我有一块手表:

$scope.$watch("ngModel", function(newValue){

// here I have complex logic to traverse newValue
// to see if it matches my current UI state
// if it matches, then I return
// if it does not match, then I sync my UI to the newValue 

});

我有一个将当前 UI 状态推送到模型的函数:

function pushSelectionToModel() {
    // some code
    $scope.ngModel = newState;
    // some code
}

一切正常,但是当用户快速滚动浏览我的 UI 指令时,每次都会触发 ngModel watch。我用于检测 newValue 是否与我当前的 UI 状态匹配的代码相当复杂,因此会导致性能问题。

一个自然的解决方案似乎是在我刚刚调用pushSelectionToModel 时忽略$watch。我不能在更新之前禁用pushSelectionToModel 中的手表,然后再启用,因为手表是在pushSelectionToModel 退出之后稍后执行的。

我如何告诉 Angular 对于某些特定的模型分配操作我不想触发某些特定的 $watch?

这里是相关的简化版Plunkr example

基本上我想防止updateUi() 在我单击应用按钮时被调用两次。但是示例被简化了,实际上我无法直接分配或比较 innerNamengModel 值,因为在我的实际代码中,由于某些转换,值会有所不同。

【问题讨论】:

  • 将问题通读两遍,但仍然很难想象发生了什么。可以加个小提琴吗?
  • 你应该重写 ngModelController.$render 方法而不是监视值。这将是正确的方法
  • @Code Apprentice - 我用 Plunkr 更新了我的问题。
  • @Pierre - 感谢您的提示,我会看看 $render。

标签: javascript angularjs watch


【解决方案1】:

我通过添加以下语句解决了类似的问题:

$scope.$watch('ngModel', function(newValue){
 if($scope.innerName !== newValue){
     // now execute code

http://plnkr.co/edit/r9sQax4VNqBraimQi9pz

但它更像是一种解决方法......

【讨论】:

  • 是的,这也是我的第一个想法。如果这些值是原始值,它会工作得很好。但在我的情况下,ngModel 和 newValue 实际上都是可能以不同顺序出现的对象数组,因此我必须进行差异计算以查看数组是否具有相同的值。当用户与我的指令交互过快时,这些差异计算会导致明显的性能问题。
猜你喜欢
  • 2010-10-23
  • 1970-01-01
  • 2016-11-27
  • 1970-01-01
  • 2016-05-24
  • 2020-06-30
  • 1970-01-01
  • 2021-02-05
  • 1970-01-01
相关资源
最近更新 更多