使用现有指令的AngularJS DOM操作

我正在尝试学习如何使用Angular方法来添加一个DOM元素,其中包含从服务返回的数据,通过从我的控制器中更改范围变量将它传递给指令。

我的服务

.factory('Poller', function($http,$q){
           return {
                poll : function(api){
                    var deferred = $q.defer();
                    $http.get(api).then(function (response) {
                            deferred.resolve(response.data);
                    });
                    return deferred.promise;
                }

            }
        });

我的控制器

.controller('accordion',['$scope','Poller','$timeout',function($scope,Poller,$timeout){
$scope.newdata = null;

function Repeater ()  {
     $scope.$apply(function () {
     Poller.poll('api/getupdates')
       .then(function(data){
           $scope.newdata = data;                                   
            });
        });
     };
    $timeout(Repeater, 1000) ;             
    var timer = setInterval(Repeater, 11000);  

我的指令

.directive( 'newreading', function () {
  return {
    scope: {'newdata' : '='},
    templateURL : 'templatenewreading.html',
    link: function ( scope, element, attrs ) {
      var el;

      scope.$watch('newdata', function () {

          console.log(scope.newdata);

      });
    }
  };
}); 

HTML //注意:这是通过ng-repeat完成的

 <accordion-group id="Device 1">  
     <newreading ></newreading> 
 </accordion-group> 

 <accordion-group id="Device 2">  
     <newreading ></newreading> 
 </accordion-group>      

 <accordion-group id="Device3">  
     <newreading ></newreading> 
 </accordion-group>      

 <accordion-group id="Device4">  
     <newreading ></newreading> 
 </accordion-group> 

我的示例JSON

{
    "readings": [                    
            "id": "Device2",
            "T01": "3",
            "L02": "35"
    ]
}

一切直到这里工作正常,我想远离使用jQuery(我知道Angular有jQuery Lite)

我的问题

首先,这是使用Angular JS向DOM添加元素的正确方法吗? 如果是,我将如何重用此指令? 目前,scope.watch会触发该函数4次(显然!!)。

我太困惑了,因为我找不到一个简单的方法来触发正确的指令来添加一个元素。

我已经通过文档的几个部分,并发现StackOverflow的问题,建议编译和添加元素,我可以做,但我需要在所需的div中添加元素。

任何帮助深表感谢。


在你的指令定义中,你写了scope: {'newdata' : '='} 。 这将做的是创建一个隔离的作用域,其中$scope.newdata双向绑定到newreading元素的属性newdata

所以,如果你的HTML没有说<newreading newdata="someVariableOnTheScope"></newreading>这是没有意义的。 我不知道你的accordion控制器的操作范围,所以我不能给你更具体的建议。

由于您使用的是相同的模板,因此您不需要额外的指令来读取新的读数。 你只想要显示额外的读数。 所以你应该更新底层模型,你的视图会自动更新。 这是Angular的魔力。

额外的读数可以添加如下(假设newData包含新的读数):

// create an object so you can lookup a device by id
var devicesById = _.indexBy($scope.data,'_id');
_.each(newData,function(device) {
  // add the new readings to the readings of the device with the correct id
  Array.prototype.push.apply(devicesById[device._id].readings,device.readings);
});

一个plunkr:http://plnkr.co/edit/iKtmrToz4fkJ46bVfcjX

一些额外的提示:

  • 如果您不需要访问attrselement请不要在链接函数中编写代码。 在指令的控制器中执行此操作
  • 你只需要将你的代码包装在$scope.$apply如果你在AngularJS范围之外做的事情,则可以使用$scope.$apply 。 你基本上对Angular说:我在这里做的东西可能改变了你所知道的DOM,再次同步。 当使用其他库时(例如JQuery),这是非常有用的。
  • 链接地址: http://www.djcxy.com/p/95239.html

    上一篇: AngularJS DOM manipulation using existing directive

    下一篇: repeat not work inside a transclusion?