2013-05-02 70 views
0

我有一個簡單的角度應用程序,像這樣: 的HTML:通知AngularJS有更新的模型

<body ng-app> 
    <div class="content" ng-controller="LeaderboardCtrl"> 
     <div class="row" ng-repeat="fb_ranking in fb_rankings"> 
      <div class="rank cell">{{fb_ranking.rank}}</div> 
      <div class="name cell">{{fb_ranking.name}}</div> 
      <div class="score cell">{{fb_ranking.score}}</div> 
     </div> 
    </div> 
</body> 

而且JS:

function change_data(){ 
    some_data[0].rank = 99; 
    var sc = angular.element(document.getElementById('overlay')).scope; 
    sc.$apply(function(){ 
     sc.fb_rankings = some_data; 
    }); 
} 

var some_data = [ 
    {rank: 1, name: 'Boink a doodledo', score: 3000}, 
    {rank: 2, name: 'Someone else', score: 300}, 
    {rank: 3, name: 'Donkey', score: 30}, 
    {rank: 4, name: 'Booger landon', score: 20}, 
]; 

function LeaderboardCtrl($scope){ 
    $scope.fb_rankings = some_data; 
} 

一切工作負載預期。但是,我想通過代碼更新模型some_data,而不是像點擊等事件。這是因爲模型更新是通過複雜的Flash和DOM交互實現的。使用ng-click或其他基於事件的指令不是一種選擇。

因此,爲了更新模型,我使用了change_data函數來修改一個屬性,然後嘗試獲取角度範圍並使用$ apply函數(根據大量教程和在線發現的帖子)。但是,當我運行change_data(),它死並出現以下錯誤: 類型錯誤:對象功能(A,d){V ...

我不知道這裏有什麼問題。或者錯誤甚至意味着什麼。 我有一個jsfiddle在這裏使用上面的代碼: http://jsfiddle.net/w2Ahr/1/

任何指針都在正確的方向將是偉大的。

回答

1
function change_data(){ 
    some_data[0].rank = 99; 
    var sc = angular.element("#overlay").scope(); 
    sc.$apply(function(){ 
     sc.fb_rankings = some_data; 
    }); 

要注意的是修改的角度這樣外面的範圍是完全錯誤的,你應該只用於演示目的做到這一點,應該修改controller

+1

謝謝!這樣可行。我清楚地忽略了.scope是一個函數,需要被調用。但我很好奇:你爲什麼說這是完全錯誤的?從Angular文檔看來,Angular在後臺執行的操作是調用$ scope。$ apply無論如何不必在控制器中調用它就是語法糖。 – 2013-05-02 05:47:34

+0

這顯然是分離的擔憂,是一個設計選擇。你的應用程序可以正常工作,但隨着它的增長,維護將會非常困難。控制器負責操作'範圍',如果你需要運行一個摘要循環(除了測試,ofc)應該在一個指令中。另外,'angular.element(xx).scope()'很慢。 – 2013-05-02 18:35:02

0

呼叫範圍內的範圍內的變量。$直接申請可引起一些問題。 它使用更安全的包裝:

// call this method to avoid '$apply already in progress' 
$scope.updateScope = function (fn) { 
    var phase = this.$root.$$phase; 
    if (phase === '$apply' || phase === '$digest') { 
     if (fn && (typeof(fn) === 'function')) { 
      fn(); 
     } 
    } else { 
     this.$apply(fn); 
    } 
}; 

然後調用:

sc.updateScope(function(){ 
    sc.fb_rankings = some_data; 
});