【问题标题】:AngularJS DOM manipulation using existing directiveAngularJS DOM 操作使用现有指令
【发布时间】:2016-01-03 00:22:58
【问题描述】:

我正在尝试通过更改控制器的范围变量来学习添加 DOM 元素的 Angular 方法,该元素从服务返回的数据传递给指令。

我的服务

.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 : 'template\newreading.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 中添加元素。

非常感谢任何帮助。

【问题讨论】:

    标签: javascript angularjs dom angularjs-directive


    【解决方案1】:

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

    因此,如果您的 HTML 没有显示 &lt;newreading newdata="someVariableOnTheScope"&gt;&lt;/newreading&gt;,这没有任何意义。我不知道你的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);
    });
    

    一个笨蛋:http://plnkr.co/edit/iKtmrToz4fkJ46bVfcjX

    一些额外的提示:

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

    【讨论】:

    • 感谢@Pieter 的提示。我理解您在我的 HTML 中包含变量的观点。我之前这样做过,但是一个元素被放置在 DOM 中,其中没有任何数据,因为数据仅在应用程序运行时接收,并且通过 Ajax 轮询从服务器接收新数据。它还需要在正确的 div 中添加元素.我不知道我会怎么做。有什么建议吗?仅供参考 - '手风琴' 是 Angular UI 手风琴 github.com/angular-ui/bootstrap/tree/master/src/accordion
    • 该属性只会指向一个变量。收到响应后,您仍可以更改变量指向的对象的内容。如果您创建一个 plunkr 或类似的东西,我想我可以为您提供更好的帮助
    • plnkr.co/edit/YSCjLRz8fJSbwedVAm5a?p=preview 。此 plunker 中的 newdata.json 将使用新的轮询数据进行更新。我不确定如何将它实时添加到现有应用程序中。再次感谢@Pieter
    • 新读数是否需要单独的指令?你想要完成的事情是这样的 (plnkr.co/edit/iKtmrToz4fkJ46bVfcjX) 吗?
    • 你是个传奇!这正是我想要做的。您能否简要解释一下方法,如果可能的话,编辑答案,以便我可以勾选答案。真的很感谢你帮助人:) @pieter
    猜你喜欢
    • 1970-01-01
    • 2017-01-23
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    • 2013-08-12
    • 1970-01-01
    相关资源
    最近更新 更多