从AngularJS中的隔离范围/指令接收广播和调用控制器功能?

时间:2013-08-02 13:43:56

标签: angularjs angularjs-scope directive

以下是jsfiddle举例说明我的情况。

首先,这是使用接收维度创建指令的正确方法吗? 然后,每个指令应该与其他指令隔离。因此我使用scope: {}

问题是调用控制器中的函数..它似乎也没有收到广播..

我确信这是一个微不足道的问题。我是Angular的新手:)

我有一个页面,我用ng-repeat加载了许多组件:

<div ng-app="test">
    <div ng-controller="containerCtrl">
        <component ng-repeat='c in components' id="c.id" my-width="{{c.width}}" my-height="{{c.height}}">
    </div>
</div>

控制器:

controller('containerCtrl', function ($scope) {
    $scope.components = [{ id: "c1", width: 100, height: 100 },
                        { id: "c2", width: 200, height: 100 },
                        { id: "c3", width: 300, height: 100 }];

    //in the actual controller I am using a socket provider and doing
    //socket.forward([
    //        'initPage',
    //        'refreshPage'
    //    ], $scope);
    //simulating it with a simple broadcast here..
    $scope.$broadcast("onSomething", "");

    $scope.doSomething = function (data) {
        alert("doing something");
    };
}).

和指令:

directive('component', function () {
        var linkFn = function(scope, element, attrs) {
            $(element).
                resizable({
                    stop: function( event, ui ) {
                        scope.emitSomething(attrs.id, ui.position);
                    }
                });

            scope.$on('onSomething', function(res) {
                alert("onSomething!");
            });
        };

        return {
            restrict: 'E',
            template: '<div class="ui-widget-content" style="width: {{width}}px; height: {{height}}px;"></div>',
            replace: true,
            scope: {
                width:'@myWidth',
                height:'@myHeight'
            },
            link : linkFn
        };
    });

1 个答案:

答案 0 :(得分:16)

控制器在链接功能之前执行,因此您的广播过早发送。您可以使用$timeout

延迟此操作
$timeout(function() {
    $scope.$broadcast("onSomething", "");
});

要从具有隔离范围的指令调用控制器方法,您需要将该方法指定为参数:

<component ng-repeat='c in components' id="c.id" my-width="{{c.width}}" 
 my-height="{{c.height}}" callbk="doSomething(data)">

您需要在指令中使用&语法:

scope: {
    width: '@myWidth',
    height: '@myHeight',
    emitSomething: '&callbk'
},

要将参数传递给该回调/控制器函数,您需要使用正确的语法:scope.localDirectiveName({arg1: ..., arg2: ...})。在小提琴中,我只使用了一个参数,并在数组中传递了两个参数:

$(element).resizable({
   stop: function (event, ui) {
      scope.emitSomething({data: ["id", "position"]});
   }
});

fiddle