如何将数据从服务传递到angular.js中的指令

时间:2016-05-20 22:43:37

标签: javascript angularjs angularjs-directive angularjs-ng-repeat

我有一个提醒服务,在页面顶部显示提醒。我编写了一个服务和一个指令,该指令以来自服务的数据为基础。

但是,当我使用teh警报服务添加服务并将其传递给指令时,它不会显示,警报

这是我的代码

模板

<div class="alert alert-{{alert.type}}">
    <button type="button" class="close" data-dismiss="alert" aria-hidden="true" ng-click="close()">&times;</button>
    <div ng-bind="::alert.message" ></div>
</div>

警报服务和指令

angular.module('test')
    .service('alertService', function() {
        var alerts = [];
        this.add = function(type, msg) {
            var self = this;
            var alert = {
                type: type,
                msg: msg,
                close: function() {
                    return self.closeAlert(alert);
                }
            };
            return alerts.push(alert);
        };
        this.closeAlert = function(alert) {
            return this.closeAlertIdx(alerts.indexOf(alert));
        };
        this.closeAlertIdx = function(index) {
            return alerts.splice(index, 1);
        };
        this.clear = function() {
            alerts = [];
        };
        this.getAlerts = function() {
            return alerts;
        };
    })
    .directive('alertList', ['alertService', function(alertService) {
        return {
            restrict: 'EA',
            templateUrl: 'templates/alert/alert.html',
            replace: true,
            link: function(scope) {
                scope.alerts = alertService.getAlerts();
            }
        };
    }]);

在index.html中,我引用了alert-list指令

<div>
   <alert-list ng-repeat="alert in alerts">
   </alert-list>
</div>

在我的控制器中,

alertService.add('info', 'This is a message');

我看到alertService将警报添加到数组中,但是当我在指令的link函数中放置一个断点时,它永远不会被调用

2 个答案:

答案 0 :(得分:1)

服务是返回对象的函数,因此您必须将服务修改为或多或少:

.service('alertService', function() {
  var alerts = [];
  return{
      add : function(type, msg) {
          var self = this;
          var alert = {
              type: type,
              msg: msg,
              close: function() {
                  return self.closeAlert(alert);
              }
          };
          return alerts.push(alert);
      },
      closeAlert: function(alert) {
         return this.closeAlertIdx(alerts.indexOf(alert));
      },
      closeAlertIdx : function(index) {
         return alerts.splice(index, 1);
      },
      clear: function() {
           alerts = [];
      },
      getAlerts: function() {
          return alerts;
      }
 })

答案 1 :(得分:1)

只有在创建指令元素时,才会调用链接函数一次。当您的应用程序启动时,将调用链接函数,并将scope.alerts设置为空列表。

我认为您需要将ng-repeat移动到警报模板的外部div,而不是alert-list元素。

由于链接函数只被调用一次,并且如果你调用alertService.clear,数组的身份可能会改变,你可能会更好地将手表放在警报的链接声明中:

link: function(scope) {
  scope.$watchCollection(alertService.getAlerts, function(alerts) {
    scope.alerts = alerts;
  });
}

由于此方法不直接执行任何DOM操作,因此现代角度最佳实践可能会将其实现为component