$onChanges 未触发

Posted

技术标签:

【中文标题】$onChanges 未触发【英文标题】:$onChanges not triggered 【发布时间】:2019-01-13 14:45:02 【问题描述】:

按模型更新但不更新模型。我应该使用 $onChanges 函数

我有一个模型

class Model 
  constructor(data) 
    this.data = data;
  
  getData() 
    return this;
  

2 个嵌套组件:

var parentComponent = 
  bindings: 
    vm: '<'
  ,
  controller: function() 
    var ctrl = this;
  ,
  template: `
    <div>
      <a ui-sref="hello.about" ui-sref-active="active">sub-view</a>
      Parent component<input ng-model="$ctrl.vm.data">
      <ui-view></ui-view>
    </div>
  `
;
var childComponent = 
  bindings: 
    vm: '<'
  ,
  template: `
    <div>
      Child component <input ng-model="$ctrl.vm.data">
      <br/>
      Child component copy<input ng-model="$ctrl.vmCopy.data">
      <br/>
      Child component doCheck<input ng-model="$ctrl.vmCheck.data">
      </div>
  `,
  controller: function() 
    var ctrl = this;
    ctrl.$onChanges = function(changes) 
      ctrl.vmCopy = angular.copy(ctrl.vm);
      ctrl.vm = ctrl.vm;
    ;
    ctrl.$doCheck = function () 
      var oldVm;
      if (!angular.equals(oldVm, ctrl.vm)) 
        oldVm = angular.copy(ctrl.vm);
        ctrl.vmCheck = oldVm;
        console.log(ctrl)
      
    
  

两者都从解析中获取数据:

.config(function($stateProvider) 
    var helloState = 
      name: 'hello',
      url: '/hello',
      resolve: 
        vm: [function() 
          return myModel.getData();
        ]
      ,
      component: 'parent'
    

    var aboutState = 
      name: 'hello.about',
      url: '/about',
      resolve: 
        vm: [function() 
          return myModel.getData();
        ]
      ,
      component: 'child'
    
    $stateProvider.state(helloState);
    $stateProvider.state(aboutState);

  )

我希望在模型更改或父级更改时更新我的​​组件,但我不希望它们更新模型。

我认为这就是为什么绑定 '

这是一个fiddle 来说明我想要做什么。

换句话说: 我希望子组件在父更改时更新,但不希望子组件更新父组件。

您可以在 fiddle 中看到,如果我直接绑定到本地范围,子级会从父级获取更新,但也会更新父级

如果我将绑定复制到本地范围,则子级不会更新父级,但也不会被父级更新。 如果

【问题讨论】:

【参考方案1】:

使用对象 content — 使用 $doCheck 生命周期挂钩1

在绑定对象或数组reference时,$onChanges 挂钩仅在引用的发生变化时执行。要检查对象或数组的 内容 的更改,请使用 $doCheck 生命周期挂钩:

app.component('nvPersonalTodo', 
  bindings: 
    todos: "<"
  ,
  controller: function()
    var vm = this;
    this.$doCheck = function () 
      var oldTodos;
      if (!angular.equals(oldTodos, vm.todos)) 
        oldTodos = angular.copy(vm.todos);
        console.log("new content");          
        //more code here
      ;
    
)

来自文档:

控制器可以提供以下方法作为生命周期钩子:

$doCheck() - 在摘要循环的每一轮调用。提供检测变化并采取行动的机会。您为响应您检测到的更改而希望采取的任何操作都必须从此挂钩中调用;实现这一点对何时调用 $onChanges 没有影响。例如,如果您希望执行 深度相等性检查,或检查 Date 对象,Angular 的更改检测器不会检测到更改并因此不会触发,则此挂钩可能很有用$onChanges. 这个钩子在没有参数的情况下被调用;如果检测到更改,您必须存储以前的值以供比较与当前值。

——AngularJS Comprehensive Directive API Reference -- Life-cycle hooks

如需了解更多信息,

AngularJS angular.equals API Reference AngularJS 1.5+ Components do not support Watchers, what is the work around?

【讨论】:

为了让我的 vm 得到通知,它可以与 $onChange 函数一起使用,但我必须删除副本(Object.assign)。我不想删除副本,我确实想在控制器中处理副本。无论如何,您的代码有效,因为您删除了副本。我尝试使用副本,但它不起作用。 下一步是create a PLNKR重现问题。 小提琴:jsfiddle.net/yvbenitah/1h07t30z/1153。我也更新了我的问题 好吧,我好像误会了什么。您的解决方案有效。谢谢

以上是关于$onChanges 未触发的主要内容,如果未能解决你的问题,请参考以下文章

iPad JavaScript onchange onblur 未触发

下拉 OnSelect 和 OnChange 操作未触发

iText onchange事件未触发

SwiftUI 工作表中未触发深层链接 onChange

SqlDependency OnChange 事件未在 IIS 服务器上触发

AutoCompleteField onchange/onselect 未触发