2

我創建了一個指令,用於監視day屬性,並在屬性值更改時檢索遠程資源。 CoffeeScript的代碼:

angular.module('app.directives').directive 'myDirective', ['$timeout', ($timeout)-> 

    DirectiveController=($scope, activityResource)-> 

     # Load activities 
     load=()-> 
      activityResource.get { 
       day: $scope.day 
       environment_id: $scope.environment.id 
      }, 
      (data)-> 
       $scope.activities = data.activities 

     # Watch environment and reload activities 
     $scope.$watch 'environment', (value) -> 
      load() 

     # Watch selected day to reload activities 
     $scope.$watch 'day', (value) -> 
      load() 
... 
] 

load方法,每次叫day變化,但結果絕不回調觸發。網絡檢查表明請求沒有發送到遠端。我發現的唯一的解決方法是使用$timeout服務推遲load方法的執行:

 $scope.$watch 'day', (value) -> 
      $timeout (()-> load()), 10 

我懷疑涉及範圍生命週期的問題,但我無法弄清楚,爲什麼我不得不推遲調用資源。

更新

資源源代碼:

resources = angular.module('app.resources', ['ngResource']) 

... 

resources.factory 'app.activityResource', ['$resource', 'app.endpoint', ($resource, endpoint)-> 
    $resource "#{endpoint()}/user/environments/:environment_id/activities/:id/:verb", 
    {environment_id: "@environment_id", id: "@id"}, 
    latest: 
    method : 'GET' 
    params: 
     verb: 'latest' 
    annual: 
    method : 'GET' 
    params: 
     verb: 'annual' 
] 

我也加入到該代碼摘錄用作參數的第二觀看屬性(environment)來查詢的資源。

更新2

我不知道,但如果它是與我們使用CORS訪問遠端(這似乎是不錯的選擇)。

+0

是否有可能爲你把你的代碼plunkr或的jsfiddle。調試代碼更簡單的演示。 –

+0

你的activityResource是什麼樣的? – DotDotDot

+0

@RishabhSinghal我試圖創建一個jsFiddle,但還沒有設法重現這個問題。 – Jef

回答

1

您未看到請求的原因是,作爲$ http調用的一部分,配置作爲承諾傳遞給每個攔截器。

https://github.com/angular/angular.js/blob/b99d064b6ddbcc9f59ea45004279833e9ea82928/src/ng/http.js#L665-L670

在角,$ Q承諾只在$消化週期的開始解決。因此,在發生$ digest循環之前,您的HTTP請求將不會被觸發,這就是爲什麼您會看到圍繞它發送$ timeout的幫助(超時會導致$摘要)。

https://github.com/angular/angular.js/blob/2a5c3555829da51f55abd810a828c73b420316d3/src/ng/q.js#L160 https://github.com/angular/angular.js/blob/3967f5f7d6c8aa7b41a5352b12f457e2fbaa251a/src/ng/rootScope.js#L503-L516

您也可以通過重新創建你所看到的錯誤狀況和看網絡請求驗證這一點。運行此之後,你會看到你的要求斷火:

angular.element("[ng-app]").scope().$digest() 

該代碼觸發關閉在$ rootScope一個$消化週期,導致您沒有得到解決有望成爲解決。

有關更多討論,請參閱此問題,因爲我同意這是令人驚訝的行爲。

https://github.com/angular/angular.js/issues/2881

+0

感謝您的回答,我懷疑這類問題。你有一個想法,爲什麼它在這個小提琴http://jsfiddle.net/jefmathiot/xCJjc/4/?我試圖真正接近我們的真實用例(點擊一個指令來改變嵌套指令中的一個屬性來觸發Ajax調用),但我無法理解爲什麼在這種特殊情況下執行$ digest循環。 – Jef

+1

我處於猜測領域而沒有看到確切的源代碼,但是如果您查看我發佈到rootScope源的鏈接,則可以看到asyncQueue正在作爲$的do/while循環的一部分進行處理消化。這實際上意味着如果您的範圍不是最後一個處理範圍,您可能會看到它按預期工作。如果它是最後一個被處理的範圍,那麼asyncQueue不會被排空,直到下一個$ digest – dherman

+0

看起來你猜得相當不錯:),但我有點迷路。在rootScope源代碼中,只要asyncQueue中有元素,do-while循環似乎就會被處理。調用資源不應該追加一個元素到這個隊列中? – Jef

相關問題