Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 跨控制器共享和观察数据_Javascript_Angularjs - Fatal编程技术网

Javascript 跨控制器共享和观察数据

Javascript 跨控制器共享和观察数据,javascript,angularjs,Javascript,Angularjs,我们正在使用一个树型导航元素,它需要允许其他指令/控制器知道: 当前选择是什么,以及 当行选择更改时 我想确定处理这个问题的最佳角度 到目前为止,我们一直在触发一个整个应用程序都能听到的事件——虽然不太理想,但确保没有任何硬编码可以直接与组件通信 但是,我们现在需要在激活另一个组件时获取当前选择。事件不会发生 所以我正在考虑一个服务,一些保存当前选择的单例,可以直接通过树进行更新,任何需要它的人都可以从中读取 然而,这也带来了一些其他问题: 是否最好完全放弃事件,让组件知道它何时更改服务的

我们正在使用一个树型导航元素,它需要允许其他指令/控制器知道:

  • 当前选择是什么,以及
  • 当行选择更改时
我想确定处理这个问题的最佳角度

到目前为止,我们一直在触发一个整个应用程序都能听到的事件——虽然不太理想,但确保没有任何硬编码可以直接与组件通信

但是,我们现在需要在激活另一个组件时获取当前选择。事件不会发生

所以我正在考虑一个服务,一些保存当前选择的单例,可以直接通过树进行更新,任何需要它的人都可以从中读取

然而,这也带来了一些其他问题:

  • 是否最好完全放弃事件,让组件知道它何时更改服务的节点ID
  • 如果我使用
    $watch
    ,似乎我应该直接公开对象-因此,除非我想使所需的
    $watch
    代码复杂化,否则使用getter/setter将无法工作

我担心的一部分是,这将允许任何组件设置值,这是我们故意不允许的-更改不会影响树,但会使服务值与真实值不同步,并将触发无效的
$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)){