2014-09-18 23 views
1

使用angularjs 1.2.21

當我不使用與$ HTTP緩存,顯然GET和異步響應之間的消化週期,因爲視覺元素在更改爲在視圖中插值的變量後在我的頁面中正確更新。 但是,當我將緩存設置爲true,並且數據來自緩存時,我的視圖停止更新,這意味着沒有摘要發生。

angularjs doc指出即使數據來自緩存,響應也是異步的。但它沒有提到消化週期。

請注意,即使響應是從緩存中提供的,數據的傳遞也是與實際請求相同的異步方式。

要解決這個問題,我需要把$ http調用放在$ timeout(func,0)中。

因此,在您看來,它是一個錯誤還是設計?

更新:@PSL I forked your plunk向您展示如何重現它。運行。您會看到第一次按下按鈕時顯示「正在加載」消息,則不會再出現。刪除緩存,它會每次出現。基本上,我試圖在獲取呼叫期間改變視圖,並在完成時恢復視圖。

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.2.21/angular.js" data-semver="1.2.22"></script> 
    <script src="app.js"></script> 
    </head> 

    <body ng-controller="MainCtrl"> 
    <p ng-show="load">Load in progress</p> 
    <p>{{i}}</p> 
    <button ng-click="refresh()">Refresh</button> 
    </body> 

</html> 



var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope, $http) { 
    $scope.name = 'World'; 
    $scope.i=0; 
    $scope.load = false; 

    $scope.refresh = function(){ 
    $scope.load = true; 
    $http.get('test.json', {cache:true}).success(function(resp){ 
    $scope.i++; 
    $scope.name = resp; 
    $scope.load = false; 
    }); 
    } 
}); 

更新2:我不認爲我能在這裏重現,因爲我實際的代碼更復雜。實際上,修改load變量被另一個指令(綁定到它)捕獲,它將重置第三方jquery模塊。當使用緩存時,jquery模塊並不總是能夠正確復位,這往往會表明得到的響應太快以至於綁定無法到達觀看它的模塊...

+0

正常工作對我.. http://plnkr.co/edit/lRoHIJ?p=preview你的問題可能是在其他地方。你可以複製它嗎? – PSL 2014-09-18 18:49:30

+0

@PSL謝謝。更新我的問題向你展示。 – 2014-09-18 19:38:01

+0

很酷。你能粘貼分叉的網址嗎? – PSL 2014-09-18 19:41:34

回答

1

看着github上的角度done()函數下面,我認爲這是一個錯誤。 (編輯 @PSL認爲這不是一個錯誤)。

但是什麼仍然是真實的是,假設出現這種方法沒有錯誤,也沒有辦法避免scope.apply() - 比$apply.$$phase是truthy等。

也許你最好的選擇是使用useApplyAsync標誌來確保它能正常工作。

完成功能在這裏:

function done(status, response, headersString, statusText) { 
    if (cache) { 
     if (isSuccess(status)) { 
     cache.put(url, [status, response, parseHeaders(headersString), statusText]); 
     } else { 
     // remove promise from the cache 
     cache.remove(url); 
     } 
    } 

    function resolveHttpPromise() { 
     resolvePromise(response, status, headersString, statusText); 
    } 

    if (useApplyAsync) { 
     $rootScope.$applyAsync(resolveHttpPromise); 
    } else { 
     resolveHttpPromise(); 
     if (!$rootScope.$$phase) $rootScope.$apply(); 
    } 
    } 

其實,在git的1.2.x版本分支,useApplyAsync不可用。你能升級到最新版本嗎?

老做功能:

function done(status, response, headersString, statusText) { 
    if (cache) { 
     if (isSuccess(status)) { 
     cache.put(url, [status, response, parseHeaders(headersString), statusText]); 
     } else { 
     // remove promise from the cache 
     cache.remove(url); 
     } 
    } 

    resolvePromise(response, status, headersString, statusText); 
    if (!$rootScope.$$phase) $rootScope.$apply(); 
    } 
+0

我不確定這是否是一個錯誤,我無法複製這個問題.. http://plnkr.co/edit/lRoHIJ?p=預覽 – PSL 2014-09-18 18:53:30

+0

好的。我確實認爲!$ rootScope。$$階段是關鍵。解決的辦法是設置useApplyAsync標誌 – 2014-09-18 18:54:47

+0

進行'$ rootScope。$$ phase'檢查以確保另一個摘要在執行'apply()'之前沒有同時運行。 – PSL 2014-09-18 18:57:52