简体   繁体   English

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

[英]how to pass data from service to directive in angular.js

I have an alert service which shows alerts on top of the page. 我有一个警报服务,该服务在页面顶部显示警报。 I have written a service and a directive which feeds off of the data coming from the service. 我已经编写了一个服务和一个指令,该指令可以馈送来自该服务的数据。

However, when i add a service using teh alert service and pass it to the directive, it does not show up, the alert 但是,当我使用警报服务添加服务并将其传递给指令时,它不会显示,警报

here is my code 这是我的代码

The template 模板

<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>

Alert Service and directive 警报服务和指令

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();
            }
        };
    }]);

In the index.html , i have referenced the alert-list directive 在index.html中,我引用了alert-list指令

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

In my controller i have, 在我的控制器中,

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

I see that the alertService adds the alert to the array, but when i put a breakpoint in the link function of the directive, it never gets called 我看到alertService将警报添加到数组,但是当我在指令的链接函数中放置断点时,它永远不会被调用

services are function that return an object, so you had to modify your service to be more or less like this: 服务是返回对象的函数,因此您必须将服务修改为大致如下所示:

.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;
      }
 })

The link function is only called once, when the directive element is created. 创建指令元素时,链接函数仅被调用一次。 When your app starts up, the link function will be called, and the scope.alerts will be set to an empty list. 当您的应用程序启动时,将调用link函数,并将scope.alerts设置为空列表。

I think you need to move the ng-repeat to the outer div of the alert template, rather than on the alert-list element. 我认为您需要将ng-repeat移到警报模板的外部div,而不是放在alert-list元素上。

Since the link function is only called once, and the identity of the array can change if you call alertService.clear , you'll probably have better luck putting a watch in your alert's link statement: 由于链接函数仅被调用一次,并且如果您调用alertService.clear ,则数组的标识可能会更改, alertService.clear ,最好在您的警报的link语句中放置一个手表:

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

Since this method doesn't directly do any DOM manipulation, modern angular best-practice would probably be to implement this as a component instead. 由于此方法不直接执行任何DOM操作,因此现代的最佳角度实践可能是将其实现为组件

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

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