【问题标题】:AngularJS $rootScope.$on is not catching or pass data with Services via routeAngularJS $rootScope.$on 没有通过路由捕获或使用服务传递数据
【发布时间】:2014-07-02 00:39:25
【问题描述】:

我想将数据从一个控制器发送到另一个控制器。其实我已经关注了这个link

我的第一个Controller是这样的:

class ProductCtrl

constructor: ($scope, @$log, @$location, @$timeout, @ProductService) ->   

    $scope.go = (path) =>
        $scope.$emit('handleEmit', @getAllProducts())
        $location.path path

第二个:

class UpdateProductCtrl

constructor: ($scope, @$log, @$routeParams) ->
    $scope.$on('handleBroadcast', (event, data) ->
        console.log(data)
    )

App.coffee:

app = angular.module('myApp', dependencies)
app.run ($rootScope, editableOptions) ->    
    $rootScope.$on 'handleEmit', (event, args) ->
        $rootScope.$broadcast 'handleBroadcast', args

当我在 ProductCtrl 中调用 $scope.$emit('handleEmit', @getAllProducts()) 时,App 内咖啡 $rootScope.$on 'handleEmit' 没有触发。请帮助我做错了什么。

【问题讨论】:

    标签: angularjs controller coffeescript


    【解决方案1】:

    从对我其他答案的评论中,我了解到 2 个控制器位于 2 条不同的路线上。使用事件来传递数据不会这样工作,因为当第一个控制器发出事件时,第二个还没有注册它的监听器。

    因此,您需要另一种方式在路由之间传递数据。您可以使用服务来执行此操作,但由于服务是全局对象,因此您需要对传递的数据进行某种范围界定和维护,以免积累垃圾或使用陈旧数据。

    您可以使用以下属性创建一个充当全局“存储”对象的服务:

    • 它可以接受用于下一条路线的数据
    • 它可以提供用于当前路线的数据

    此服务在内部维护两个“桶”。所有put 操作都在nextRouteBucket 上执行,所有get 操作都在currentRouteBucket 上执行。当 Angular 的路由器广播 $routeChangeStart 事件时,服务会切换存储桶并进行清理。

    class NavScope
      constructor: ($rootScope) ->
        @currentRouteBucket = {}
        @nextRouteBucket = {}
    
        $rootScope.$on '$routeChangeStart', () =>
          @currentRouteBucket = @nextRouteBucket
          @nextRouteBucket = {}
    
      put: (name, data) ->
        @nextRouteBucket[name] = data
    
      get: (name) ->
        @currentRouteBucket[name]
    

    下一个路由上的控制器可以简单地调用navScope.get 'someKey' 来从上一个路由中检索数据,或者在路由resolve 对象中检索它们(参见plunker)。

    请记住,这只是一个原型,可能存在一些极端情况,例如当用户使用浏览器“后退”和“前进”导航或路由失败时。您始终必须在 URL 上放置关联的 ID,以便如果您在 navScope 上找不到数据,请从服务器检索它们。

    查看 plunker here

    【讨论】:

    • " 错误:[$injector:unpr] Unknown provider:NavScopeProvider
    • 你有没有在你的 "Route2Ctrl" 中遇到过以下错误 "Error: [$injector:unpr] Unknown provider: messageProvider
    【解决方案2】:

    我已经用您的代码制作了这个coffeescript plunker,它似乎工作正常。没有任何 CoffeeScript 特性。

    检查run 回调是否确实运行,或检查事件名称中的拼写错误。

    不过有一个建议:当您需要控制器之间的“消息总线”式通信时,最好发布仅存在于$rootScope 级别的事件。让$rootScope 向下广播事件可能会很昂贵,因为它必须遍历整个范围层次结构。想象一下,您页面中某处的 ng-repeat 创建 500 个子作用域的惩罚。我知道,它是程序性的 fors、while 和 ifs,但是——无论如何——它是不需要运行的代码。

    你可以简单地写:

    app = angular.module('plunker', [])
    
    class ProductCtrl
      constructor: ($scope, $rootScope) ->
        $scope.go = () ->
          $rootScope.$emit 'MyEvent', {message: 'Hello!'}
    
    app.controller 'ProductCtrl', ProductCtrl
    
    class UpdateProductCtrl
      constructor: ($scope, $rootScope) ->
        unsubscribe = $rootScope.$on 'MyEvent', (event, data) ->
          $scope.message = data.message
        $scope.$on '$destroy', unsubscribe
    
    app.controller 'UpdateProductCtrl', UpdateProductCtrl
    

    这样,run 回调就完全不需要了。 看看here

    【讨论】:

    • 当然了s working fine. I think the problem is that i'll open another page thats 为什么第一个控制器神奇地消失了。
    猜你喜欢
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 2015-03-20
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多