我一直在将自定义指令升级到新的组件体系结构。我读过,组件不支持观察者。这样对吗?如果是这样,您如何检测对象的变化?对于一个基本示例,我有一个自定义组件myBox,该组件具有一个子组件游戏,并带有对游戏的绑定。如果游戏组件中有找零游戏,如何在myBox中显示警告消息?我知道有rxJS方法可以纯粹在角度上做到这一点吗?我的JSFiddle
myBox
JavaScript
var app = angular.module('myApp', []); app.controller('mainCtrl', function($scope) { $scope.name = "Tony Danza"; }); app.component("myBox", { bindings: {}, controller: function($element) { var myBox = this; myBox.game = 'World Of warcraft'; //IF myBox.game changes, show alert message 'NAME CHANGE' }, controllerAs: 'myBox', templateUrl: "/template", transclude: true }) app.component("game", { bindings: {game:'='}, controller: function($element) { var game = this; }, controllerAs: 'game', templateUrl: "/template2" })
HTML
<div ng-app="myApp" ng-controller="mainCtrl"> <script type="text/ng-template" id="/template"> <div style='width:40%;border:2px solid black;background-color:yellow'> Your Favourite game is: {{myBox.game}} <game game='myBox.game'></game> </div> </script> <script type="text/ng-template" id="/template2"> <div> </br> Change Game <textarea ng-model='game.game'></textarea> </div> </script> Hi {{name}} <my-box> </my-box> </div><!--end app-->
在没有观察者的情况下编写组件
该答案概述了在不使用观察程序的情况下用于编写AngularJS 1.5组件的五种技术。
ng-change
$onChanges
$doCheck
有哪些可选方法可以在不使用watch来准备AngularJs2的情况下观察obj状态的变化?
您可以使用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。
$watch
$scope
在 1.5.3版中 ,AngularJS向服务添加了$onChanges生命周期挂钩$compile。
$compile
从文档中:
控制器可以提供以下用作生命周期挂钩的方法: $ onChanges(changesObj)-每当单向(<)或插值(@)绑定更新时调用。的changesObj是散列的键是已更改的绑定的属性的名称,和值是以下形式的对象{ currentValue: ..., previousValue:...}。使用此挂钩可触发组件内的更新,例如克隆绑定值,以防止外部值的意外突变。 — AngularJS综合指令API参考- 生命周期挂钩
控制器可以提供以下用作生命周期挂钩的方法:
<
@
changesObj
{ currentValue: ..., previousValue:...}
— AngularJS综合指令API参考- 生命周期挂钩
该$onChanges钩用于与外部变化引入组分反应<单向绑定。该ng-change指令用于ng- model通过&绑定从组件外部的控制器传播更改。
ng- model
&
在 1.5.8版中 ,AngularJS向服务添加了$doCheck生命周期挂钩$compile。
控制器可以提供以下用作生命周期挂钩的方法: * $doCheck()-在摘要循环的每个回合上调用。提供机会来检测更改并采取措施。您希望对检测到的更改做出响应的任何操作都必须从此挂钩中调用。实现这一点对何时$onChanges调用没有影响。例如,如果您希望执行深度相等检查或检查Date对象,而Angular的更改检测器无法检测到该更改,因此不会触发,则此钩子可能很有用$onChanges。该钩子不带任何参数调用;如果检测到更改,则必须存储以前的值以与当前值进行比较。 — AngularJS综合指令API参考- 生命周期挂钩
* $doCheck()-在摘要循环的每个回合上调用。提供机会来检测更改并采取措施。您希望对检测到的更改做出响应的任何操作都必须从此挂钩中调用。实现这一点对何时$onChanges调用没有影响。例如,如果您希望执行深度相等检查或检查Date对象,而Angular的更改检测器无法检测到该更改,因此不会触发,则此钩子可能很有用$onChanges。该钩子不带任何参数调用;如果检测到更改,则必须存储以前的值以与当前值进行比较。
$doCheck()
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开发人员指南》-组件间通信
Extensions/rx.angular.js)从服务推送值
例如,在您的服务处于保持状态的情况下该怎么办?如何将更改推送到该服务,页面上的其他随机组件会意识到这种更改?最近一直在努力解决这个问题
使用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。
DataService.subscribe
DataService.set
在上PLNKR DEMO。