• 用postal.js在AngularJS中实现订阅发布消息


    postal.js

    用postal.js在AngularJS中实现event bus

    理想状态下,在一个AngularJS应用中,控制器都应该是相互独立的代码单元,它们之间不应该有任何的相互引用。但是有些时候,你还是需要让控制器在你的应用中相互交流。例如你现在有一个叫做Orders的控制器,它需要告诉一个叫做Cart的控制器其中需要添加一个新项目。

    实现这种类型的交流方式的最好的方法之一就是使用event bus。

    postal.js正是一个在JS中实现了event bus的库。

    一、Postal.js是什么?

    1. Postal.js是一个使用Javascript编写的,位于内存中的message bus,它收到了AMQP的一些启发。Postal.js在浏览器中运行,同时也可以使用Node.js在服务器端运行。它采用了JS程序员很熟悉的“事件类型”编程范式,同时通过提供“broker”以及更加精巧实现的subscriber来扩展了事件类型。

    你可以使用postal在特定的频道中发布消息。通过这种方式,你可以将你的消息分割为app,cart,ui等不同类型。它同时也使用了envelope设计模式来方式你的订阅回调中有n个变量。

    二、用法

    1.在使用postal.js时,你可以轻松的装饰$scope,并为它添加一个叫做$bus的方法来允许你和其他的控制器进行交流:

     1 angular.module('myApp')  
     2     .config(function ($provide) {
     3         $provide.decorator('$rootScope', ['$delegate', function ($delegate) {
     5             Object.defineProperty($delegate.constructor.prototype, '$bus', {
     7                 value: postal,
     8                 enumerable: false
     9             });
    10 
    11             return $delegate;
    12         }]);
    13     });

     为减轻内存泄漏问题,需要监听$destroy事件,调用unsubscribe方法。上面的代码变为:

     1 angular.module('introToAngularApp')  
     2 .config(function ($provide) {
     3     $provide.decorator('$rootScope', ['$delegate', function ($delegate) {
     4         Object.defineProperty($delegate.constructor.prototype, '$bus', {
     5             get: function() {
     6                 var self = this;
     7 
     8                 return {
     9                     subscribe: function() {
    10                         var sub = postal.subscribe.apply(postal, arguments);
    11                         // 监听$destroy事件
    12                         self.$on('$destroy', function() {
    13                             sub.unsubscribe(); // 调用unsubscribe方法
    14                         });
    15                     },
    16                     channel: postal.channel,
    17                     publish: postal.publish
    18                 };
    19             },
    20             enumerable: false
    21         });
    22 
    23         return $delegate;
    24     }]);
    25 });

    2.现在,你的控制器已经拥有了postal.js,你可以通过下面的代码来使用它:

     1 angular.module('myApp')  
     2     .controller('CartCtrl', ['$scope', function ($scope) {
     3         $scope.$bus.subscribe({    // 订阅
     4             channel: 'orders',
     5             topic: 'order.new',
     6             callback: function(data, envelope) {
     7                 console.log('it worked', data, evenlope);
     8             }
     9         });
    10     }
    11 ])
    12     .controller('OrderCtrl', ['$scope', function ($scope) {
    13         $scope.order = function() {
    14             $scope.$bus.publish({    // 发布
    15               channel: 'orders',
    16               topic: 'order.new',
    17               data: { /* order info */ }
    18           });
    19         };
    20     }
    21 ]);

    在CartCtrl中,$scope.$bus.subscribe方法被调用。这个订阅被设置来监听orders频道上主题为order.new的所有消息。当一个消息的主题能够匹配上的时候,callback函数将会被调用。

    在OrderCtrl中,$scope.$bus.publish方法在$scope.order方法被调用时被调用。它将会在正确的频道上发布一条消息,并使用正确的主题来触发订阅。发布出去的data将会被订阅中的callback收到,注意callback中还包含一个envelope,它是接收到的数据的一个包装。

    三、总结

    通过使用$bus装饰器,你可以让控制器之间的交流变得非常轻松。当然除了postal.js之外,还有很多其他的event bus库可以选择。

    参考资料1:【https://github.com/postaljs/postal.js

    参考资料2:【http://jonathancreamer.com/an-angular-event-bus-with-postal-js/

  • 相关阅读:
    生成函数trick
    带权并查集维护二分图
    关于二项式反演的一些思考
    CSP集训记录
    解决Maven版本冲突
    蚂蚁金服5轮面试,最后栽这了...
    配置交换机Eth-Trunk+VRRP+MSTP+接口BFD状态联动+Telnet示例
    企业园区网络建设技术方案(华为)
    网络三层架构
    SOA治理
  • 原文地址:https://www.cnblogs.com/softwarefang/p/6398248.html
Copyright © 2020-2023  润新知