Javascript 跨控制器共享和观察数据
我们正在使用一个树型导航元素,它需要允许其他指令/控制器知道:Javascript 跨控制器共享和观察数据,javascript,angularjs,Javascript,Angularjs,我们正在使用一个树型导航元素,它需要允许其他指令/控制器知道: 当前选择是什么,以及 当行选择更改时 我想确定处理这个问题的最佳角度 到目前为止,我们一直在触发一个整个应用程序都能听到的事件——虽然不太理想,但确保没有任何硬编码可以直接与组件通信 但是,我们现在需要在激活另一个组件时获取当前选择。事件不会发生 所以我正在考虑一个服务,一些保存当前选择的单例,可以直接通过树进行更新,任何需要它的人都可以从中读取 然而,这也带来了一些其他问题: 是否最好完全放弃事件,让组件知道它何时更改服务的
- 当前选择是什么,以及
- 当行选择更改时
- 是否最好完全放弃事件,让组件知道它何时更改服务的节点ID李>
- 如果我使用
,似乎我应该直接公开对象-因此,除非我想使所需的$watch
代码复杂化,否则使用getter/setter将无法工作$watch
我担心的一部分是,这将允许任何组件设置值,这是我们故意不允许的-更改不会影响树,但会使服务值与真实值不同步,并将触发无效的
$watchs
实现getter不应导致复杂的$watcher:
服务:
angular.service('myService', function() {
var privateVar = 'private';
return {
getter: function() {
return privateVar;
};
});
控制器:
angular.controller('myController', function(myService){
$scope.watch(myService.getter, function(){
//do stuff
};
});
请参阅此插件:实现getter不应导致复杂的$watcher: 服务:
angular.service('myService', function() {
var privateVar = 'private';
return {
getter: function() {
return privateVar;
};
});
控制器:
angular.controller('myController', function(myService){
$scope.watch(myService.getter, function(){
//do stuff
};
});
请看下面这个例子:我认为使用服务应该是可行的,您不需要任何观察者 在下面的演示中或在此演示中,我添加了以下内容:
sharedData
存储数据-选择和项目sharedDataEvents
component2
中显示值,我使用了单向绑定,因此该组件无法更改选择
此外,将数据与事件分离还可以防止组件更改选择。因此,只有MainController
和Component1
可以更改选择
如果打开浏览器控制台,可以看到侦听器正在运行。只有component3
的侦听器正在做一些事情(在3次选择更改后,它将发出警报),其他侦听器只是将新选择记录到控制台
angular.module('demoApp',[])
.controller('MainController',MainController)
.指令(“组件1”,组件1)
.指令(“组件2”,组件2)
.指令(“组件3”,组件3)
.factory('sharedData',sharedData)
.factory(“sharedDataEvents”,sharedDataEvents);
功能主控制器(共享数据){
sharedData.setItems([{
id:0,
测试:“你好,0”
}, {
id:1,
测试:“你好1”
}, {
id:2,
测试:“你好2”
}]);
this.items=sharedData.getItems();
this.selection=this.items[0];
}
函数组件1(){
返回{
限制:'E',
作用域:{},
bindToController:{
选择:'='
},
模板:“Comp1选择:{{comp1Ctrl.selection}}”+
“- {{{item}
”,
控制器:函数($scope、sharedData、sharedDataEvents){
this.items=sharedData.getItems();
this.select=功能(项目){
//控制台日志(项目);
this.selection=项目
股份数据(项目);
};
sharedDataEvents.addListener('onSelect',函数(已选择){
log('选择更改了comp.1侦听器回调',已选择);
});
},
控制器:“comp1Ctrl”
};
}
函数组件2(){
返回{
限制:'E',
作用域:{},
bindToController:{
选择:“@”
},
模板:“Comp2选择:{{comp2Ctrl.selection}}”,
控制器:功能(sharedDataEvents){
sharedDataEvents.addListener('onSelect',函数(已选择){
log('选择更改了comp.2侦听器回调',已选择);
});
},
控制器:“comp2Ctrl”
};
}
函数组件3(){
//每三次变化时只倾听并保持警惕
返回{
限制:'E',
控制器:函数($window,sharedDataEvents){
var计数=0;
sharedDataEvents.addListener('onSelect',函数(已选择,旧){
log('selection changed comp.3 listener callback',selected,old);
如果(++计数===3){
计数=0;
$window.alert('选择更改了3次!!!被组件3检测到');
}
});
}
}
}
函数SharedData(sharedDataEvents){
返回{
选择:{},
项目:[],
setItems:函数(项){
this.items=项目
},
设置选择:功能(项目){
此选项=项目;
sharedDataEvents.onSelectionChange(项目);
},
getItems:function(){
归还此物品;
}
};
}
函数SharedDataEvents(){
返回{
更改侦听器:{
onSelect:[]
},
addListener:函数(类型,cb){
this.changeListeners[type].push({cb:cb});
},
onSelectionChange:功能(选择){
控制台日志(选择);
var changeEvents=this.changeListeners['onSelect'];
console.log(changeEvents);
如果(!changeEvents.length)返回;
angular.forEach(更改事件、函数(cbObj)){