扩展AngularJS组件之间的通信

时间:2017-09-24 19:22:10

标签: javascript angularjs components communication

我们在应用程序中有各种不在父/子或兄弟关系中的组件。假设一个复选框,当处于检查状态时,应该改变另一个组件的状态,该组件位于一个完全不同的容器中。

该应用程序有500多个不同的视图,因此每个视图的控制器都不是一个选项。这些交互也是完全自定义的,因此我们需要数十种方法来覆盖所有这些方法(选项卡复选框,选项卡的多个复选框,更多复选框的复选框等)。

这里最好的行动方案是什么?到目前为止,我们考虑了通过id注册组件的全局可用服务,然后订阅依赖组件以监听服务中该特定id的状态更改(例如,在ng-if指令中切换),或者使用Redux。我们以前没有这种复杂关系的经验。

非常感谢任何想法或类似经历。

2 个答案:

答案 0 :(得分:0)

您描述的Observer模式正在使用事件选择器($broadcast $emit)在angularjs中实现,因此无需创建独立服务。

基于组件的应用程序的要点是具有一些树结构体系结构。因此,在这些情况下,子组件通知父母,然后父母可能会通知其他孩子并继续。

如果您的应用程序结构不是这样的,您可能会考虑重构,但现在您可以绑定一些事件发射器。

答案 1 :(得分:0)

要解决此问题,请使用允许松散耦合架构publish/subscribe pattern

在AngularJS应用程序中,一个很棒的库postaljs允许轻松实现这种模式:

定义app.config一个$bus $范围变量,该变量可在应用程序的所有位置访问:controlers,directives,...

app.config(function($provide) {
    $provide.decorator('$rootScope', [
        '$delegate',
        function($delegate) {
            Object.defineProperty($delegate.constructor.prototype,
                '$bus', {
                    get: function() {
                        var self = this;
                        return {
                            subscribe: function() {
                                var sub = postal.subscribe.apply(postal, arguments);
                                self.$on('$destroy',
                                    function() {
                                        sub.unsubscribe();
                                    });
                            },
                            channel: function() {
                                return postal.channel.apply(postal, arguments);
                            },
                            publish: function() { postal.publish.apply(postal, arguments); }
                        };
                    },
                    enumerable: false
                });
            return $delegate;
        }
    ]);
});

发布
发布项目已更新。

var channel = $scope.$bus.channel('myresources');
channel.publish("item.updated", data);

在列表上发布更新

var channel = $scope.$bus.channel('myresources');
....
channel.publish("list.updated", list);

<强>订阅 需要在“myresources”频道上通知事件的控制器/指令。

 var channel = $scope.$bus.channel("myresources");
 ....
 //The wildcard * allow be notified on item/list. updated
 channel.subscribe("*.updated", function(data, envelopment) {
   doOnUpdated(); 
 });