如何同步控制器创建和发出事件?

时间:2016-04-01 14:14:32

标签: angularjs

如果您遇到这个问题以及如何解决这个问题,我感兴趣。我有一个页面,它有它的控制器,在该页面中,每个选项卡都有自己的控制器。根据我访问页面的方式,通过导航或直接URL链接,我发现外部控制器引发事件时标签控制器尚未就绪。我的解决方案是引发“ControllerCreated”事件,将控制器的实例作为事件arg传递。来自每个标签控制器。外部控制器监听这些并调用它们“加载”操作。是否有其他内置方式来同步这个而不必提高自定义事件?

1 个答案:

答案 0 :(得分:0)

事件记录服务

一种方法是将外部事件存储在服务中,并让子控制器使用该服务“赶上”并订阅事件。

app.service("eventRecorder", function() {
    var lastEvent;
    var subscriberIdNum = 0;
    var subscriberList = {};

    this.record = function evRecorder (eventValue) {
        lastEvent = eventValue;
    };

    this.subscribe = function evSubscribe(callbackFn) {
        //callback for subscriber to "catch-up"
        if (lastEvent) { callbackFn(lastEvent) };
        //save subscriber
        subscriberIdNum++
        var subscriberIdString = 'id'+subscriberIdNum;
        subscriberList[subscriberIdString] = callbackFn;
        //return unSubscribe function
        return function unSubscribe() {
             delete subscriberList[subscriberIdString];
        };
    };

    this.notify = function evNotify( eventValue ) {
        this.record(eventValue);
        angular.forEach(subscriberList, function (cb) {
            cb(eventValue);
        });
    };
});

客户端控制器示例

app.controller("client", function($scope, eventRecorder) {
     var vm = $scope;

     var unSubscribe = eventRecorder.subscribe(function(value) {
         //callback executes immediately to "catch-up"
         vm.eventValue = value;
     });

     $scope.$on('$destroy', unSubscribe);
});

父控制器使用

app.controller("parent", function($scope, eventRecorder) {
     var vm = $scope;

     vm.onEvent(value) {
         eventRecorder.notify(value);
     });
});

为了防止内存泄漏,控制器应该在破坏范围时取消修改。

此示例显示仅提供一个Feed的事件记录器服务。它可以推广到处理更多的一个Feed。

更新:自动取消订阅

  

“为了防止内存泄漏,控制器应该在破坏范围时取消修改。”我知道你的意思,我们有类似的通知服务,但我们把它拉了出来,因为有人会忘记取消订阅。

可能需要范围作为subscribe函数参数并实现自动取消定义。

    this.subscribe = function evSubscribe(scope, callbackFn) {
        //callback for subscriber to "catch-up"
        if (lastEvent) { callbackFn(lastEvent) };
        //save subscriber
        subscriberIdNum++
        var subscriberIdString = 'id'+subscriberIdNum;
        subscriberList[subscriberIdString] = callbackFn;

        var unSubscribe = function evUnsubscribe() {
            delete subscriberList[subscriberIdString];
        };

        scope.$on("$destroy", unSubscribe);

        return unSubscribe;

    };