2015-10-06 52 views
3

我想學習角度的方式添加一個DOM元素與從服務返回的數據,通過從我的控制器更改範圍變量傳遞給指令。AngularJS 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 : 'template\newreading.html', 
    link: function (scope, element, attrs) { 
     var el; 

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

      console.log(scope.newdata); 

     }); 
    } 
    }; 
}); 

HTML //注意:這是由NG-重複

<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在遠離所有(我知道有角jQuery的精簡版)

我的問題

首先,這是使用Angular JS向DOM添加元素的正確方法嗎?如果是,我將如何重用此指令?目前,scope.watch會觸發該函數4次(顯然!!)。

我太困惑了,因爲我找不到一個簡單的方法來觸發正確的指令來添加一個元素。

我已經通過文檔的幾個部分,發現StackOverflow的問題,建議編譯和添加元素,我可以做但我需要添加元素在所需的div。

任何幫助,非常感謝。

回答

1

在你的指令定義中,你寫了scope: {'newdata' : '='}。這將做的是創建一個隔離範圍,其中$scope.newdata雙向綁定到newreading元素的屬性newdata

所以,如果你的HTML不說<newreading newdata="someVariableOnTheScope"></newreading>這沒有任何意義。我不知道你的控制器在什麼範圍內工作,所以我不能給你更具體的建議。

由於您使用的是相同的模板,因此看起來您不需要額外的指令來讀取新的讀數。你只想要顯示額外的讀數。所以你應該更新底層模型,你的視圖會自動更新。這是Angular的魔力。

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

一些額外的提示:

  • 不要寫

    額外的讀數如下(假設newData包含新的讀數)加入代碼在鏈接功能,如果你不需要訪問attrselement。在指令

  • 的控制器中執行此操作如果您正在處理AngularJS範圍之外的事情,則只需將代碼包裝在$scope.$apply中。你基本上對Angular說:我在這裏做的東西可能改變了你所知道的DOM,再次同步。當使用其他庫(例如JQuery)時,這也是非常有用的
+0

感謝提示@Pieter。我明白你的觀點,在我的HTML中包含變量。我之前做過,但是一個元素放置在DOM中,沒有任何數據,因爲只有在應用程序運行時纔會收到數據,並且通過Ajax輪詢從服務器接收到新數據。還需要將元素添加到正確的div中。我不知道我該怎麼做。任何建議?僅供參考 - '手風琴'是有角度的UI手風琴https://github.com/angular-ui/bootstrap/tree/master/src/accordion – iveedee

+0

該屬性只會指向一個變量。收到響應後,您可以更改仍然更改變量指向的對象的內容。我想我可以幫助你更好,如果你想創建一個plunkr或類似的東西 –

+0

http://plnkr.co/edit/YSCjLRz8fJSbwedVAm5a?p=preview。這個plunker中的newdata.json將更新有關輪詢的新數據。我不確定如何將其實時添加到現有的應用程序中。再次感謝@Pieter – iveedee