简体   繁体   English

分散的AngularJS组件之间的通信

[英]Communication between spread out AngularJS components

We have various components in the application that are not in parent/child or sibling relationships. 我们在应用程序中具有不具有父/子或同级关系的各种组件。 Let's say a checkbox that when in checked state is supposed to change the state of another component which is in a completely different container. 假设有一个复选框,当处于选中状态时,该复选框应更改处于完全不同的容器中的另一个组件的状态。

The application is over 500 different views, so a controller for each one is not an option. 该应用程序有500多个不同的视图,因此每个视图都没有一个控制器。 Those interactions are also completely custom, so we would need tens of methods to cover all of them (checkbox to tab, multiple checkboxes to tab, multiple checkboxes to more checkboxes etc). 这些交互也是完全自定义的,因此我们将需要数十种方法来涵盖所有交互(复选框到选项卡,多个复选框到选项卡,多个复选框到更多复选框等)。

What is the best course of action here? 最好的做法是什么? So far we thought about a globally available service to register components by id and then subscribe the dependent components to listen for the status change on that particular id in the service (for example in an ng-if directive to toggle), or use Redux. 到目前为止,我们考虑了一种全球可用的服务,该服务可以通过id注册组件,然后订阅从属组件以侦听该服务中该特定id的状态更改(例如,使用ng-if指令进行切换),或使用Redux。 We have no previous experience with complex relationships like that. 我们以前没有类似复杂关系的经验。

Any ideas or similar experiences would be greatly appreciated. 任何想法或类似的经验将不胜感激。

The Observer pattern as you describe it is being implemented in angularjs with event emmiters ( $broadcast $emit ) so there is no need to create an independent service. 您所描述的Observer模式是通过带有事件发射器( $broadcast $emit )的angularjs实现的,因此无需创建独立的服务。

The point of component based applications is to have some tree structured architecture. 基于组件的应用程序的重点是要具有一些树形结构。 So in those cases the child component notifies the parent and then the parent notifies some other child maybe and goes on. 因此,在这些情况下,子级组件会通知父级,然后父级可能会通知其他某个子级,然后继续。

If your application is not structured like this you might consider a refactoring but for now you could just bind some event emitters. 如果您的应用程序的结构不是这样,则可以考虑进行重构,但是现在您可以绑定一些事件发射器。

To solve this issue use the publish/subscribe pattern that allow get a loosely-coupled architecture . 要解决此问题,请使用允许松散耦合的体系结构发布/订阅模式

On an AngularJS application a great library is postaljs that allow implements this pattern easely: 在AngularJS应用程序上,一个很棒的库是postaljs ,可以轻松实现此模式:

Define at app.config a $bus $scope variable that will be accesible on all places of the application: controlers, directives, ... 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;
        }
    ]);
});

Publish 发布
Publish on item updated. 发布已更新的项目。

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

Publish on list updated 在列表上发布更新

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

Subscribe The controller/directive that needs be notified for an event on the "myresources" channel. 订阅需要在“ myresources”通道上通知事件的控制器/指令。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM