2013-10-15 16 views
0

有以下問題。如何使用外部數據更新ng-model?

考慮,我們有以下的HTML代碼:

<div id="container" ng-controller="Controller"> 
    <my-tag ng-model="values"></my-tag> 
</div> 

而下面的控制器:

var Controller = myApp.controller("Controller", function ($scope, $http, $filter, $q) { 

    $scope.values = []; 

    $http.get(someURLHere).then(function(response) { 
     var data = JSON.parse(response.data); 
     $scope.values = data; 
    }); 

     /* And so on ... */ 

}); 

,這裏是指令聲明:

myTag.directive('myTag', function() { 
    return { 
     require: "^ngModel", 
     restrict: "E", 
     replace: true, 
     scope: { 
      ngModel : "=", 
     }, 
     controller: ['$scope', '$filter', myTagController], 
     templateUrl: /* Here is a path to my template*/,   
     link: function (scope, elem, attrs, ctrl) { 

      scope.data = scope.ngModel;   

     } 
    } 
}); 

標籤「我的 - 標籤「是我的自定義指令。它通過ng-model獲取一些數據並呈現它們。 而ng-controller="Controller"是一些使用AJAX檢索某些數據的函數,它假設將它們寫入$scope.values。之後,我預計他們將通過ng-model="values"發送到my-tag。接下來,假設數據在HTML頁面上呈現。但他們不! 我相信我的數據已在Controller中正確檢索,但在my-tag中更新ng模型時出現問題。 將Controller中檢索的數據「發送」到我的自定義指令的ng模型的最佳方法是什麼?

+0

請添加您的指令代碼 – Sprottenwels

回答

1

僅在$ scope.apply()中更新範圍變量。爲您的代碼

例子:

var Controller = myApp.controller("Controller", function ($scope, $http, $filter, $q) { 

      $scope.values = []; 

      /* 
       Getting values via AJAX - assigned to ajaxvalues 
      */ 
      //still in callback from ajax: 
      $scope.$apply(function() { 
       $scope.values = ajaxvalues; 
      }); 
      //... end callback 
     }); 

詳情請參見:http://docs.angularjs.org/api/ng $ rootScope.Scope

+0

但我使用控制檯的控制檯調試和類似console.log($ scope.value)顯示我想要的值。但他們不轉移到我的標籤。 –

+1

這裏可能有兩個問題:首先控制檯日誌是由你直接觸發的,所以它總是打印出來。當Angular檢測到更改時,會觸發DOM更新(您的狀態的HTML表示)。如果它是外部(f.e.ajax)回調,Angular不知道更改。第二個問題可能是一個孤立的範圍。最容易弄清楚你是否首先檢查了應用方法。 – Thomas

+0

''console.log''會顯示更新後的數據,因爲''scope.values''實際上更新爲新值。你的問題很可能是因爲你的代碼在AngularJS環境之外運行,AngularJS仍然不知道你對範圍做了修改。 AngularJS不會對值更改進行髒檢查,而只是在它認爲可能發生更改(即,像控制器這樣的AngularJS相關代碼已運行)時纔對安全資源進行檢查。但是,這可能會在將來消失,這要歸功於Object.observe。 –

1

如果你的上的數據變化不是在視圖中反映,這幾乎是每一個時間,因爲你做的在AngularJS框架之外的東西。這例如適用於事件處理程序,它適用於XMLHttpRequest的回調。所以我假設你正在使用後者來獲取你的數據。您可能需要檢查AngularJS的$http服務,它可以正確處理這個問題。在回調中,您可以設置範圍變量。但由於AngularJS有這個所謂的承諾不錯的功能,你甚至可以做這樣的事情:

$scope.values = $http.get('http://my.url/') 
    .then(function(response){return response.data;}); 

這實際上綁定的承諾(這是以後解決)至$ scope.values,但AngularJS知道這是一個承諾,它不會嘗試以任何方式顯示它。當數據到達後,.then函數將被調用,在這個例子中,這個函數只是從響應中返回JSON數據。 AngularJS會以正確的方式自動處理這些信息,然後將該JSON數據放入$scope.values

如果您確實需要或想要使用像XMLHttpRequest或具有未通過AngularJS觸發其他代碼,您將需要通過包裝代碼到$scope.$apply()這樣做AngularJS知道你正在做更改範圍:

$scope.$apply(function(){ 
    $scope.values = response.data; 
}); 

但是,你很可能會利用$http更好。一些像Restangular一樣的包裝,或者如果需要的話編寫你自己的包裝。如果你這樣做的話,儘量使用承諾,因爲它會使代碼更容易和可重用。想象一下:

function makeRequest(id) { 
    return $http.get('...some URL using id...') 
    .then(function(response){return response.data;}); 
} 

$scope.variable1 = makeRequest(1); 
$scope.variable2 = makeRequest(5); 
$scope.variable3 = makeRequest(7); 

從關係上來說,你需要複雜的回調函數來知道把數據放在哪裏。在這裏,你的回調函數根本不需要關心,因爲AngularJS及其承諾能夠完成所有的魔術。

+0

很好,謝謝。但是,你能寫一個簡單的例子來告訴內部元素(這是我的自定義標籤)從外部元素(這是我的控制器正在做Ajax查詢)?我試過了,但是不起作用...問題出在這個通知上...... –

+0

由於sprottenwels之前問過你:請提供你的指令的源代碼。 –

+0

完成。我已經更新了我的第一篇文章,現在指令聲明就在那裏。 –

相關問題