簡體   English   中英

如何使用角度承諾作為字符串的一部分

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM