[英]How to use angular promise as part of a string
我正在尋找有關處理承諾和字符串創建的通用解決方案。 基本上是時間問題。 該代碼不是實際的代碼,但是說明了我的問題和嘗試的解決方案。
我有兩個需要組合的json對象。 一個或兩個對象可能具有需要API提供某些信息的值。 此信息用於創建一個標簽,該標簽顯示已合並的兩個對象。
具有定義標簽的對象(無需查找):
var object1 = {
type: "some.type",
distribution: 50,
label: "Male"
}
具有動態標簽的對象(以及通過服務$ http請求獲取標簽的偽代碼):
var object2 = {
type: "some.type",
distribution: 50,
value: "68"
}
// call service to get the data to populate the label
myService.getDynamicObjectData("68").then(function(response){
// should be "Alaska"
object2.label = response.data.label;
});
所需組合:
var combinedObj = {
type: "some.type.combined",
distribution: 25,
// ideally label would be "Male > Alaska"
label: object1.label + " > " + object2.label
values: [object1, object2]
}
我的問題是,直到創建組合對象(尤其是標簽字符串)后,才填充object2.label。 在視圖中,我看到“男性>未定義”。 我設法達到“男性> 68”的水平,但這並沒有真正的幫助。 當我不合並對象時,只要解決了諾言,標簽就會更新,並且讓“阿拉斯加”和“雄性”顯示為兩個唯一條目沒有問題。 當我組合並從兩個標簽創建字符串時,它發生得太快了。
object1和object2在服務中創建,該服務處理數據讀取並創建供內部使用的此類對象,然后,此組合代碼在另一個服務中,用於處理此類數據的嵌套; 因此我無法真正使用觀察程序來更新該值。
我嘗試將標簽設置為希望可以工作的諾言,但沒有成功:
var promise = myService.getDynamicObjectData("68").then(function(response){
// should be "Alaska"
object2.label = response.data.label;
});
var object2 = {
type: "some.type",
distribution: 50,
value: "68",
label: promise
}
標簽只是其中包含{then(),catch(),finally()}的對象。 我無法找到一種方法來獲取實際的返回值,即使then()返回正確的值也是如此。
我嘗試使用數組和過濾器,以便直到最后一刻才真正創建字符串,這意味着既然字符串不是“真實的”,那么它應該在模型最終更新時起作用(如分別顯示對象時會執行此操作):
var combined = {
type: "some.type.combined",
distribution: 25,
label: [object1.label, object2.label]
values: [object1, object2]
}
module.filter('labelFilter', function(){
return function(input){
if(angular.isArray(input)){
// but input[1].label is a promise object, how do I get the resolved value?
return input[0].label + " > " + input[1].label
}
return input;
}
});
因此,我正在求助於社區,看看我在這里能做些什么。 如何創建一個字符串,其中該字符串的一部分基於promise的結果? 我認為,如果我使用$ resource,則可以設置label:labelResource,並且labelResource最終將解析為所需的實際數據(即使是所需數據的父對象也將有所幫助)。 不幸的是,對於$ resource來說,還有其他邏輯太復雜了,所以我不能在沒有一點重構的情況下使用它。 我希望能夠將label設置為$ q.deferred.result之類的東西,並使其全部解決(即使我仍然需要過濾器)。
無論如何,感謝您的光臨!
你可以用promise和$ q來做
https://docs.angularjs.org/api/ng/service/ $ q轉到頁面底部,您可以在其中找到$ q.all,這基本上是解決問題的方法,當所有諾言都得到解決時,您可以調用您的函數以連接字符串(標簽)
您可以嘗試檢查此處提到的方法以在過濾器中進行操作。
我做了一個簡單的小提琴,展示了異步過濾器,您可以將其用作此問題的起點-> http://jsfiddle.net/7eqsc/5/
angular.module('myApp', [])
.controller('myCtrl', function ($scope, $timeout) {
})
.filter('test', function ($q, $timeout) {
var cache={};
return function (input) {
if (!cache[input]){
//I used timeout, but anything that needs to happen async can happen here
$timeout(function () {
//do something with the input
cache[input]=input+'!';
}, 500);
//return something in the meanwhile to hold it
return 'loading';
}
else return cache[input];
}
});
當然沒有經過測試,但可以嘗試以下方法:
module.filter('labelFilter', function () {
var cache = {};
return function (input) {
var cachedItem = cache[inputHash(input)];
if (!cachedItem) {
if (angular.isArray(input)) {
input[0].label.then(function (text) {
//once the promise is finished, put the correct verison inside the cache
cache[inputHash(input)].label = text + " > " + input[1].label;
})
//meanwhile, return the unmodified object.
return input;
}
}
return cachedItem;
}
//you'll have to identify each input for the cache somehow.. it can be a combination of fields for example
function inputHash(input) {
return input.id; //some unique identifier..
}
});
只是要記住,將promise稱為“標簽”可能會非常混亂,您應該嘗試重新組織代碼,以便更清晰地了解道具內部是否包含promise。
祝好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.