这个答案概述了在不使用观察者的情况下编写 AngularJS 1.5 组件的五种技术。
使用ng-change
指令
哪些 alt 方法可用于观察 obj 状态变化而无需使用 watch 来为 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 综合指令 API 参考 — 生命周期钩子
该$onChanges
钩子用于通过<
单向绑定对组件的外部更改做出反应。该ng-change
指令用于通过绑定从ng-model
组件外部的控制器传播更改。&
使用$doCheck
生命周期钩子
在1.5.8 版本中,AngularJS$doCheck
为服务添加了生命周期钩子$compile
。
从文档:
控制器可以提供以下方法作为生命周期钩子:
$doCheck()
- 在摘要循环的每一轮调用。提供检测变化并采取行动的机会。必须从这个钩子中调用您为响应检测到的更改而希望采取的任何操作;实现这一点对何时$onChanges
调用没有影响。例如,如果您希望执行深度相等检查或检查 Date 对象,Angular 的更改检测器不会检测到更改,因此不会触发,则此挂钩可能很有用$onChanges
。这个钩子是不带参数调用的;如果检测到更改,则必须存储以前的值以与当前值进行比较。
— AngularJS 综合指令 API 参考 — 生命周期钩子
组件间通信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 开发人员指南 - 组件间通信
例如,在您拥有一个保持状态的服务的情况下呢?我怎样才能将更改推送到该服务,页面上的其他随机组件才能知道这种更改?最近一直在努力解决这个问题
使用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
。
PLNKR 上的演示。