此答案概述了在不使用 watchers. 的情况下编写 AngularJS 1.5 组件的五种技术
使用ng-change 指令
哪些 alt 方法可用于在不使用 watch 的情况下观察 obj 状态变化以准备 AngularJs2?
您可以使用ng-change 指令对输入更改做出反应。
<textarea ng-model='game.game'
ng-change="game.textChange(game.game)">
</textarea>
并且要将事件传播到父组件,需要添加事件处理程序作为子组件的属性。
<game game='myBox.game' game-change='myBox.gameChange($value)'></game>
JS
app.component("game", {
bindings: {game:'=',
gameChange: '&'},
controller: function() {
var game = this;
game.textChange = function (value) {
game.gameChange({$value: value});
});
},
controllerAs: 'game',
templateUrl: "/template2"
});
并且在父组件中:
myBox.gameChange = function(newValue) {
console.log(newValue);
});
这是今后的首选方法。 AngularJS 使用$watch 的策略是不可扩展的,因为它是一种轮询策略。当$watch 的听众数量达到 2000 左右时,UI 变得迟缓。 Angular 2 中的策略是使框架更具响应性,并避免将$watch 放在$scope 上。
使用$onChanges 生命周期钩子
在版本 1.5.3 中,AngularJS 将 $onChanges 生命周期挂钩添加到 $compile 服务。
来自文档:
控制器可以提供以下方法作为生命周期钩子:
- $onChanges(changesObj) - 每当单向 (
<) 或插值 (@) 绑定更新时调用。 changesObj 是一个散列,其键是已更改的绑定属性的名称,值是{ currentValue: ..., previousValue: ... } 形式的对象。使用此钩子触发组件内的更新,例如克隆绑定值以防止外部值的意外突变。
— AngularJS Comprehensive Directive API Reference -- Life-cycle hooks
$onChanges 钩子用于通过< 单向绑定对组件的外部更改做出反应。 ng-change 指令用于通过 & 绑定从组件外部的 ng-model 控制器传播更改。
使用$doCheck 生命周期钩子
在版本 1.5.8 中,AngularJS 将 $doCheck 生命周期挂钩添加到 $compile 服务。
来自文档:
控制器可以提供以下方法作为生命周期钩子:
-
$doCheck() - 在摘要循环的每一轮调用。提供检测变化并采取行动的机会。必须从这个钩子中调用您为响应检测到的更改而希望采取的任何操作;实现这一点对何时调用 $onChanges 没有影响。例如,如果您希望执行深度相等检查,或检查 Date 对象,Angular 的更改检测器不会检测到更改,因此不会触发$onChanges,则此挂钩可能很有用。这个钩子是不带参数调用的;如果检测到更改,则必须存储以前的值以与当前值进行比较。
— AngularJS Comprehensive Directive API Reference -- Life-cycle hooks
与require的组件间通信
指令可以require其他指令的控制器来实现彼此之间的通信。这可以通过为require 属性提供对象映射在组件中实现。对象键指定所需的控制器(对象值)将在其下绑定到所需组件的控制器的属性名称。
app.component('myPane', {
transclude: true,
require: {
tabsCtrl: '^myTabs'
},
bindings: {
title: '@'
},
controller: function() {
this.$onInit = function() {
this.tabsCtrl.addPane(this);
console.log(this);
};
},
templateUrl: 'my-pane.html'
});
欲了解更多信息,请参阅AngularJS Developer Guide - Intercomponent Communicatation
使用RxJS 从服务推送值
例如,如果您的服务处于保持状态,那该怎么办。我怎样才能将更改推送到该服务,页面上的其他随机组件才能知道这种更改?最近一直在努力解决这个问题
使用RxJS Extensions for Angular 构建服务。
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/rx/dist/rx.all.js"></script>
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script>
var app = angular.module('myApp', ['rx']);
app.factory("DataService", function(rx) {
var subject = new rx.Subject();
var data = "Initial";
return {
set: function set(d){
data = d;
subject.onNext(d);
},
get: function get() {
return data;
},
subscribe: function (o) {
return subject.subscribe(o);
}
};
});
然后只需订阅更改即可。
app.controller('displayCtrl', function(DataService) {
var $ctrl = this;
$ctrl.data = DataService.get();
var subscription = DataService.subscribe(function onNext(d) {
$ctrl.data = d;
});
this.$onDestroy = function() {
subscription.dispose();
};
});
客户端可以使用DataService.subscribe 订阅更改,生产者可以使用DataService.set 推送更改。
DEMO on PLNKR。