2

我认为我想做的事情相当简单,但我似乎无法使用 Angular 确定正确的架构。

我想要一个 MessageCenter,以便任何控制器或其他 Angular 代码都可以添加消息。我认为正确的方法是使用 MessageCenter 服务。我会在需要的地方注入服务,然后调用 MessageCenter.add()。我遇到的问题是如何编译克隆的 DOM 指令,因为 $compile 需要一个 $scope,而我没有从服务中获得它。

这是我正在尝试的。我不确定对此的正确方法是什么。

<div>
  <div id="msg-proto" message-center-msg class="alert alert-success"></div>
</div>

然后:

.factory('MessageCenter', function($compile) {
  var that = {}

  that.add = function(type, message) {
    var n = $("#msg-proto"),
        n2 =  n.clone();
    n.parent().append($compile(n2));
  }

  return that;
});

我正在注入并调用服务:

.controller('SomeCtrl', function(MessageCenter) {
  MessageCenter.add('some msg');
});

message-center-msg定义了一个指令,为元素添加一些行为。但为了实现这一点,它需要$compile'd',我不知道如何让这一切工作。我只从服务中得到“错误:需要参数'范围'”

如何设置一个全局消息中心,它能够克隆/添加消息并处理消息 dom 元素的指令?

4

3 回答 3

3

您的服务不应像您尝试那样直接与 DOM 交互。如果我正在设计这样一个系统,我会:

  1. 有一个服务,它只接收消息并将它们放在一个数组中(如果你想支持整个消息列表)或者只是记住最后一条消息(如果你只想支持一条消息)
  2. 有一个控制器,它将消息服务注入它并将来自服务的消息绑定到它的范围内
  3. 然后有一点 HTML(或自定义指令)使用上面的控制器迭代消息并显示它们

这就是我的意思(在这里插入:http: //plnkr.co/Eps1Gy

索引.html:

<!doctype html>
<html>
  <head>
    <script src="bower_components/angular/angular.js"></script>
    <script src="scripts/app.js"></script>  
    <script src="scripts/controllers/messages.js"></script>
    <script src="scripts/controllers/click.js"></script>
    <script src="scripts/services/messageService.js"></script>
</head>
  <body ng-app="messagesApp">
    <h1>Messages</h1>
    <div ng-controller="MessagesCtrl"> 
      <ul  ng-repeat="message in messages">
        <li>{{message}}</li>
      </ul>
    </div>
    <a ng-href="#" ng-controller="ClickCtrl" ng-click="addMessage()" >Add a new message!</a>
  </body>
</html>

消息服务.js:

function MessageService() {
    this.messages = [];
    this.add = function(msg) {
        this.messages.push(msg);
    }
}

angular.module('messagesApp')
    .service('messageService', MessageService);

消息.js:

angular.module('messagesApp')
  .controller('MessagesCtrl', function ($scope, messageService) {
    $scope.messages = messageService.messages;
  });

点击.js:

angular.module('messagesApp')
  .controller('ClickCtrl', function ($scope, messageService) {
    var count = 0;

    $scope.addMessage = function() {
        messageService.add('Test message ' + count++);
    }
  });

应用程序.js:

angular.module('messagesApp', [])
  .config(function ($routeProvider) {
    $routeProvider
      .otherwise({
        redirectTo: '/'
      });
  });

就像我说的,如果你想要一些复杂的交互,你可以用自定义指令替换处理消息的 HTML,但重要的是你不要试图从你的服务中获取视图。服务应该只与定义良好的模型交互。

于 2013-09-29T06:55:42.157 回答
2

不久前我实现了一些完全相同的东西,最近将它作为凉亭组件公开。也许您可以使用或解决它:https ://github.com/IanShoe/angular-message-center

快乐编码!

于 2013-10-11T15:23:13.237 回答
0

你可以敞开心扉:)

在您调用 MessageCenter 时,将 $scope 作为参数移动,例如 MessageCenter.add("", $scope);

或者......您可以在启动时将 MessageCenter 暴露给全局范围,就像这个人建议的那样

于 2013-09-29T06:40:55.787 回答