【问题标题】:Communication between spread out AngularJS components分散的 AngularJS 组件之间的通信
【发布时间】:2018-03-05 18:11:52
【问题描述】:

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

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

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

任何想法或类似经验将不胜感激。

【问题讨论】:

    标签: javascript angularjs components communication


    【解决方案1】:

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

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

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

    【讨论】:

    • 我基本上每个视图需要 1 个控制器来知道如何处理发出的事件的部分呢?有没有办法让它们更通用,所以我可以从 HTML 模板控制它们?
    【解决方案2】:

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

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

    app.config 处定义一个$bus $scope 变量,该变量可在应用程序的所有位置访问:控制器、指令...

    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(); 
     });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-15
      • 2014-12-21
      • 2014-10-06
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      • 2016-06-09
      相关资源
      最近更新 更多