[英]How can I create an Angular factory with a getter and setter method without running into a race condition
我正在創建一個工廠以從一個頁面獲取一個userId,調用REST API,然后在以下視圖上返回結果。 我最初的嘗試主要是從這個答案中獲取的,但是-毫不奇怪-我一直陷入這種情況,即及時沒有響應並且get()
方法返回一個空數組。
這是工廠本身
app.factory('GetMessages', function() {
var messages = []
function set(userId) {
Restangular.all('/api/messages/').getList({'_id': userId}).then(function(docs){
messages = docs
})
}
function get() {
return messages;
}
return {
set: set,
get: get
}
});
對於什么值,我毫不費力地將userId傳入工廠,因為它只是通過這樣的函數傳遞的
視圖:
<a ng-click='passToFactory(message.user.id)' href='/home/inbox/reply'>Reply</a>
控制器:
$scope.passToFactory = function(id) {
GetMessages.set(id);
};
而以下視圖的控制器只是$scope.messages = GetMessages.get()
我遇到的問題是,在工廠返回空集之后,無法識別出工廠的其他更改(即使經過一段時間后,它的確從API獲得了正確的響應),並且$scope.messages
仍然為空。
我嘗試將API調用移至get方法(由於get方法通常無法及時獲取userId
,因此無法正常工作),而且我找不到找到使用諾言來強制get()
方法。等待set()
完成。
我寧願在最終解決方案中繼續使用Restangular,但這是一件很小的事情,它花費了太多時間,因此任何修復都可以。
我不是Angular的新手,所以我敢肯定有些事情是完全顯而易見的,但現在我迷路了。 謝謝。
您所具有的競爭條件是.then
方法中的函數在調用set函數之后異步執行。 如果get函數在 $q
服務履行諾言之前執行,則get函數返回一個空數組。
解決方案是保存承諾和承諾中的 鏈條 。
app.factory('GetMessages', function() {
var promise;
function set(userId) {
promise = Restangular.all('/api/messages/').getList({'_id': userId});
}
function get() {
return promise;
}
return {
set: set,
get: get
}
});
在您的控制器中,從承諾中獲得連鎖 。
GetMessages.get.then( function (docs) {
$scope.messages = docs;
}) .catch ( function (error) {
//log error
};
有關鏈接承諾的更多信息,請參見AngularJS $ q服務API參考-鏈接承諾 。
重新分配它時,您將破壞對原始messages
數組的引用。
嘗試:
Restangular.all('/api/messages/').getList({'_id': userId}).then(function(docs){
messages.concat(docs) ; // keep same array reference
});
一個簡單的例子來解釋為什么它不起作用
var arr = [];
var x = arr;
arr = [1,2,3]; // is now a different array reference
console.log(x); // is still empty array. x !== arr now
cherlietfl是對的。
問題是由於您為get函數中的消息分配了新的數組,因此您破壞了對message數組的引用。 但是concat
也這樣做。
嘗試這個:
Restangular.all('/api/messages/').getList({'_id': userId}).then(function(docs){
messages.splice(0, messages.length); // clear the array
messages.push.apply(messages, docs); //add the new content
});
嘗試將功能分配給示波器。 然后在模型中調用該函數。 像這樣:
// controller
$scope.getMessages = GetMessages.get;
視圖:
<div ng-repeat="message in getMessages()"></div>
這樣,當請求調用完成並且摘要周期再次通過觀察程序時,將調用get函數,您將獲得消息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.