什么是实现事件以在服务和其他任何事情之间进行通信的最佳方式?

时间:2014-09-15 19:31:13

标签: angularjs events service

因此,假设我有一个news服务的控制器。每当新闻发布时,控制器都想显示最新消息。我宁愿不使用$broadcast$on,因为这会对组件耦合的方式产生奇怪的影响。不依赖news的组件仍然可以监听这些事件。

所以,这是我希望能够做到的:

myApp.controller("myController", ["news", function(news){
    news.onPublish.addListener(function(story){
        ... Show the latest juicy story.
    });
}]);

news.onPublish将是一个Event实例,Event定义如下:

Event = function(){
  var listeners = [];

  this.addListener = function(l){
    listeners.push(l);
  }

  this.trigger = function(){
    var params = arguments
    listeners.map(function(l){
      l.apply(undefined, params);
    });
  }

  return this
}

这是实现服务和其他组件之间通信的好方法吗?另外,最好在$rootScope.$apply结束时拨打Event.trigger,以便听取听众所做的任何更改?

1 个答案:

答案 0 :(得分:1)

最好是编写存储工厂的公共数据,以便为您完成工作。这是一个工作示例:http://jsfiddle.net/9L5xL8sx/,它显示了这是如何工作的。 NewsService工厂可以在几个Angular模块中使用,也可以在同一模块中使用,如我的示例所示。

这是JS:

var app = angular.module("TestSharing", []);

app.factory("NewsService", [function() {
    var articles = [];
    var makeNews = function (text) {
        articles.push({text: text});
    };
    var getNews = function() {
        return articles;
    };
    return {
        get: getNews,
        make: makeNews 
    };
}]);

app.controller("FirstCtrl", ["$scope", "NewsService", function($scope, NewsService) {
    $scope.articles = function () {
        return NewsService.get();
    };
}]);

app.controller("SecondCtrl", ["$scope", "NewsService",  function($scope, NewsService) {
    $scope.articletext = "";
    $scope.submit = function () {
        NewsService.make($scope.articletext);
    };
}])

HTML:

<div ng-app="TestSharing">
    <div ng-controller="FirstCtrl">
        <span ng-repeat="article in articles()">{{article.text}}<br/></span>
    </div>
    <div ng-controller="SecondCtrl">
        <input type="text" ng-model="articletext"/>
        <button ng-click="submit()">Make some news</button>
    </div>
</div>

此外,像这样的服务也可以共享事件。例如,如果您使用工厂公开一个名为somethingNew的对象,该对象仅包含在其中一个已经共享的控制器中发生了新事件的情况,则可以实现相同的效果。我们的想法是只听取你想要的变化(使用类似$scope.$watch(NewsService.somethingNew, function (now, then) {…})之类的东西),这样就很容易了。