为什么指令不接收广播消息?

时间:2016-06-18 07:58:39

标签: angularjs angularjs-directive angularjs-scope

我有两个相互通信的指令。 初始化 krCanvasDirective 后,它会发送广播通知CanvasController.initialized 另一个指令 krCanvasWidthControlDirective 侦听此通知,当它收到通知时,它会将另一个广播通知发送回第一个指令canvas.change-width。但是对于一些我不知道的原因(初始化顺序?) krCanvasDirective 没有收到它......

krCanvasDirective.js.erb

//= depend_on_asset "canvas_directive.html.erb"

(function() {

    angular
        .module('catcher.widgets')
        .directive('krCanvas', canvasDirective);


    function canvasDirective() {
        return {
            restrict: 'EA',
            scope: {},
            replace: true,
            templateUrl: '<%= asset_path("canvas_directive.html") %>',
            controller: CanvasController,
            controllerAs: 'vm',
            link: function(scope, element, attrs) {
                var image = element.find('.preview-image');

                scope.$on('canvas.change-width', function(e, params) {                    
                    image.css({'width': params.newWidth + 'px'});
                });

            }
        }
    }

    CanvasController.$inject = ['$scope', '$rootScope',  '_'];
    function CanvasController($scope, $rootScope, _) {
        var vm = this;

        vm.canvas = {};

        activate();
        /////////////

        function activate() {
            console.log('CanvasController: activate');
            $rootScope.$broadcast('CanvasController.initialized');
        }

    }

})();

krCanvasWidthControlDirective.js.erb

//= depend_on_asset "canvas_width_control_directive.html.erb"

(function() {

    angular
        .module('catcher.widgets')
        .directive('krCanvasWidthControl', canvasWidthControlDirective);


    function canvasWidthControlDirective() {
        return {
            restrict: 'EA',
            scope: {},
            replace: true,
            templateUrl: '<%= asset_path("canvas_width_control_directive.html") %>',
            controller: CanvasWidthControlController,
            controllerAs: 'vm'
        }
    }

    CanvasWidthControlController.$inject = ['$scope', '$rootScope',  '_'];
    function CanvasWidthControlController($scope, $rootScope, _) {
        var vm = this;

        vm.canvasWidth = 500;
        vm.changeCanvasWidth = changeCanvasWidth;

        activate();
        /////////////

        function registerWatchers() {
            $scope.$on('CanvasController.initialized', function() {                
                vm.changeCanvasWidth();
            });

            $scope.$watch('vm.canvasWidth', function(newValue, oldValue) {
                if (!angular.equals(newValue, oldValue)) {
                    // WHY IT WORKS? 
                    // krCanvasDirective successfully receives notification from the method below 
                    vm.changeCanvasWidth();
                }
            });
        }

        function activate() {
            console.log('CanvasWidthControlController: activate');
            registerWatchers();
        }

        function changeCanvasWidth() {
            $rootScope.$broadcast('canvas.change-width',
                                 { newWidth: vm.canvasWidth });
        }

    }

})();

1 个答案:

答案 0 :(得分:0)

所以,正如我在评论中所说的那样 - $ rootScope可以用作全局应用程序级广播机制。我的代码没有用,因为我选择了一个错误的地方来拨打我的$ broadcast - 它应该放在link方法内(在我的特殊情况下)。

canvasDirective.$inject = ['$rootScope'];
    function canvasDirective($rootScope) {
        return {
            restrict: 'EA',
            scope: {},
            replace: true,
            templateUrl: '<%= asset_path("canvas_directive.html") %>',
            controller: CanvasController,
            controllerAs: 'vm',
            link: function(scope, element, attrs) {
                var image = element.find('.preview-image');

                scope.$on('canvas.change-width', function(e, params) {
                    image.css({'width': params.newWidth + 'px'});
                });

                $rootScope.$broadcast('canvasDirective:link.initialized');

            }
        }
    }