在 AngularJS 1.6 中交流兄弟组件之间的变化

Communicate changes between sibling components in AngularJS 1.6

我有一个 AngularJS 1.6 应用程序,如下所示:

angular.module('app').component('parent', {
    template: '    
      <parent>
         <display options="ctl.options"></display>
         <controls options="ctl.options"></controls>
      </parent>',
    controller: function() {
      this.options = { x: 100, y: 0.2 };
    },
    controllerAs: 'ctl',
    bindToController: true
});

我想使用 controls 组件中的输入来修改 options 对象的属性,以便更改反映在 display 中(但无需每次都重写整个对象一个 属性 已更改)。

我该怎么做?即使我在 controls 中将选项设置为双向绑定,display 也不会更新并且 $onChanges 不会触发。

可以使用 $watch 或 messages 轻松完成,但我想不出一个合适的以组件为中心的方法来完成它。

$onChanges 生命周期挂钩仅在对象的 identity 发生变化时触发。如果要检查对象的 内容 的更改,请使用 $doCheck 生命周期挂钩。

来自文档:

Life-Cycle Hooks

  • $doCheck() - Called on each turn of the digest cycle. Provides an opportunity to detect and act on changes. Any actions that you wish to take in response to the changes that you detect must be invoked from this hook; implementing this has no effect on when $onChanges is called. For example, this hook could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not be detected by AngularJS's change detector and thus not trigger $onChanges. This hook is invoked with no arguments; if detecting changes, you must store the previous value(s) for comparison to the current values.

-— AngularJS $compile Service API Reference - Life-cycle hooks

另见

一种声明式的方法是让工厂存储数据,并将工厂传递给每个控制器。当任一 controller/component 更新状态时,它将反映在另一个 controller/component 中。

var app = angular.module('app', []);

app.factory('Options', function(){
  return {
    data: {
      x: 100,
      y: 0.2
    }
  };
});

app.controller('DisplayCtrl', function($scope, Options){
  $scope.options = Options.data;
});

app.controller('ControlsCtrl', function($scope, Options){
   $scope.options = Options.data;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="DisplayCtrl">
    <p>x: {{ options.x }}</p>
    <p>y: {{ options.y }}</p>
  </div>
  <div ng-controller="ControlsCtrl">
     <label>
        x: <input type="number" ng-model="options.x">
     </label>
     <label>
        y: <input type="number" ng-model="options.y">
     </label>
  </div>
</div>

看到 Share data between AngularJS controllers for more thoughts. I think 是最佳答案,因为它是如此明确且易于推理,这也是我在这里回答的基础。