2013-06-21 40 views
1

我有一個自定義更新方法的資源:

angular.module('user.resources', ['ngResource']). 
factory('User', function($resource) { 
    var User = $resource('/user/:id', {}, { 
    update: { 
     method: 'PUT' 
    } 
    }); 

    User.prototype.update = function(cb) { 
    console.log('foo'); 
    return User.update({ 
     id: this._id 
    }, angular.extend({}, this, { 
     _id: undefined 
    }), cb); 
    }; 

我通過範圍通過這個資源,自定義指令:

directive('avatarUpload', function($http) { 
    return { 
    restrict: 'E', 
    scope: { 
     model: '=' 
    }, ... 

和我打電話的指令控制器上的BTN點擊更新方法:

$scope.model.update(function() { 
    console.log('bar'); 
}); 

行爲whic h困惑我atm是,第一次打印'foo'而不是'bar'時點擊按鈕,第二次打印'bar'然後點擊'foo'。任何更多的點擊總是打印'酒吧',然後'富'。

PUT請求僅在第二次點擊時觸發,而後一次點擊則從第一次觸發。

注意:我一直在控制器中使用資源更新方法,直到試圖從指令調用它。我正在使用角1.1.4 我做這個資源傳遞,因爲我想指令工作在不同類型的資源。

回答

7

很難說如果沒有看到實時代碼的例子,但我認爲你使用1.1.x系列中的AngularJS(所謂的「不穩定分支」)。如果是這樣,你面臨的問題與AngularJS中的新特性相關聯 - 版本1.1.4(此commit)中引入的HTTP請求攔截器。

新引入的請求攔截器基於$q(基於承諾),AngularJS世界承諾僅作爲$digest週期的一部分解決。換句話說,您需要進入「AngularJS世界」($digest週期)才能解決承諾。

使用基於承諾的請求攔截器,有一個承諾可以在調用$http之前解決。如前所述,只有在輸入$digest週期後才能解決此承諾。如果您從AngularJS外部啓動$http(DOM事件,setTimeout等),則不會發生這種情況。

AngularJS $resource基於$http,所以上述討論也適用於$resource

所以,假設,上述假設是正確的,你要開始從AngularJS之外$resource通話(你是在談論一個自定義的指令,所以我會押注於DOM事件)你應該簡單地包裹$resource呼叫進入scope.$apply

請注意,包裹$resource調用到$timeout(如在另一響應的建議),而將「修復」您的問題(這將迫使一個$消化循環,因此承諾將得到解決)是不正確的做法。問題在於它會強制瀏覽器離開當前的JavaScript上下文,並無需輸入重新繪製上下文。它會讓你的應用程序變慢,並可能導致UI閃爍。

+0

真棒回答,歡呼! –