Ionic-AngularJS:向父母发送事件仅重新播放给发生事件的儿童

时间:2015-07-10 21:25:18

标签: angularjs events angularjs-scope ionic

这可能听起来有点模糊,但我仍在学习并试图了解其工作原理。

我开始使用'侧菜单'启动离子项目,它已经设置了一个urlrouter配置,带有'app'抽象状态/视图/控制器以及一些带有自己控制器的其他状态。

.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider

  .state('app', {
    url: "/app",
    abstract: true,
    templateUrl: "templates/menu.html",
    controller: 'AppCtrl'
  })


  .state('app.home', {
    url: "/home",
    views: {
      'menuContent': {
        templateUrl: "templates/home.html",
        controller: 'HomeCtrl'
      }
    }
  })

  .state('app.page2', {
    url: "/page2",
    views: {
      'menuContent': {
        templateUrl: "templates/page2.html",
        controller: 'Page2Ctrl'
      }
    }
  });
  // if none of the above states are matched, use this as the fallback
  $urlRouterProvider.otherwise('/app/home');
})

在App Controller(AppCtrl)中,我正在侦听一个名为repeatMyEvent的事件,它会广播一个名为myEvent的事件。

我在myEvent事件的每个其他控制器中都有一个监听器。当我从任何其他控制器发出repeatMyEvent事件时(我在模板上有一个调用testEmit()函数的按钮),我只看到发出repeatMyEvent事件的控制器响应myEvent事件。似乎也许只有控制器的视图当前可见才响应它。但是,我希望所有控制器都能响应它。

angular.module('starter.controllers', [])

.controller('AppCtrl', function($scope, $ionicModal, $timeout) {
  // Form data for the login modal


  $scope.$on('repeatMyEvent', function(event, args) {
    console.log('repeatMyEvent event received');


    $scope.$broadcast('myEvent');

  });



})

.controller('HomeCtrl', function($scope, $stateParams) {


  $scope.$on('myEvent', function(event, args) {
    console.log('HomeCtrl received myEvent');


  });

  $scope.testEmit = function() {
    $scope.$emit('repeatMyEvent');
  }


})

.controller('Page2Ctrl', function($scope, $stateParams) {


    $scope.$on('myEvent', function(event, args) {
        console.log('Page2Ctrl received myEvent');


    });

    $scope.testEmit = function() {
        $scope.$emit('repeatMyEvent');
    }


})

;

我能理解这一点的唯一方法是抽象状态的控制器不是单例,我的每个控制器都有自己的版本。或者我是否完全误解了$ scope应该如何与控制器相关?

所有这些的后续操作是如何使其工作,以便所有控制器响应来自AppCtrl的广播消息。

注意:我也尝试过$ scope。$ root,我也有同样的行为。

2 个答案:

答案 0 :(得分:0)

控制器被实例化,$ scope DI'd => link (不是单身人士);

从我在路由器中看到的内容,您有三个单独的页面,每个页面都有自己的URL。我很好奇你为什么要在你的特定DOM甚至没有呈现时让你的控制器进行交谈。

如果在加载时必须为每个页面维护某种类型的数据对象,则可以创建在初始应用程序加载时运行并包含您的值的工厂/服务。然后只需DI进入需要该服务数据的每个控制器。

此外,这是广播和发射工作的方式。

                   3
               --------
              |        |
             ---     ----
            1   |    2   |
          ---  ---  --- ---
          |  | |  | | | | |

查看此树。你如何回答以下问题? 注意:还有其他方法,但在这里我们将讨论广播和发射。 此外,当阅读下面的文本时,假设每个数字都有自己的文件(指令,控制器)e.x. one.js,two.js,three.js。

  1. 1 如何与 3 对话?
  2. 在文件one.js

    scope.$emit('messageOne', someValue(s));
    

    在文件three.js

    scope.$on('messageOne', someValue(s));
    
    1. 2 如何与 3 对话?
    2. 在文件two.js

      scope.$emit('messageTwo', someValue(s));
      

      在文件three.js

      scope.$on('messageTwo', someValue(s));
      
      1. 3 如何与 1 和/或 2 对话?
      2. 在文件three.js

        scope.$broadcast('messageThree', someValue(s));
        

        在文件one.js&& two.js 您要捕获消息的文件

        scope.$on('messageThree', someValue(s));
        
        1. 2 如何与 1 对话?
        2. 在文件two.js

          scope.$emit('messageTwo', someValue(s));
          

          在文件three.js

          scope.$on('messageTwo', function( event, data ){
            scope.$broadcast( 'messageTwo', data );
          });
          

          在文件one.js

          scope.$on('messageTwo', someValue(s));
          

          <强>无论其

          当你让所有这些嵌套的子节点试图像这样进行通信时,你会很快看到许多$ on的$ broadcast和$ emit的。这就是我喜欢做的事情。

          在PARENT NODE (本例中为三个......)

          所以,在文件three.js

          scope.$on('pushChangesToAllNodes', function( event, message ){
            scope.$broadcast( message.name, message.data );
          });
          

          现在,在任何子节点中,您只需 $ emit 消息或使用 $ on 捕获消息。

          注意:通常很容易在一个嵌套路径中串口而不使用$ emit,$ broadcast或$ on,这意味着大多数用例都适用于您尝试获取< strong> 1 与 2 进行通信,反之亦然。

          1. 2 如何与 1 对话?
          2. 在文件two.js

            scope.$emit('pushChangesToAllNodes', sendNewChanges());
            
            function sendNewChanges(){
              return { name: 'talkToOne', data: [1,2,3] };
            }
            

            在文件three.js

            We already handled this one remember?
            

            在文件one.js

            scope.$on('talkToOne', function( event, arrayOfNumbers ){
              arrayOfNumbers.forEach(function(number){
                console.log(number);
              });
            });
            

            您仍然需要对要捕获的每个特定值使用$ on,但现在您可以在任何节点中创建任何您喜欢的内容,而无需担心如何在父级差距中获取消息

            希望这会有所帮助......

答案 1 :(得分:0)

我无法解决具体的沟通问题,因为正如@Wawy在我原帖中的评论所指出的那样,

  

设置状态配置的方式,只有一个控制器   同时活跃。因为您要用new替换视图   每次页面更改时的内容。

因此,为了处理我的具体问题(这是为了让一个控制器告诉另一个控制器刷新其数据),我只是重新组织了我的代码,将数据刷新功能放在AppCtrl中,然后每个其他控制器都可以发出一个事件告诉它执行数据刷新。