2014-06-13 5 views
0

약속 및 문자열 생성 처리와 관련된 일반적인 해결책을 찾고 있습니다. 기본적으로 타이밍 문제. 이 코드는 실제 코드가 아니지만 내 문제와 시도한 솔루션을 보여줍니다.angle promise를 문자열의 일부로 사용하는 방법

나는 내가 결합해야 할 2 개의 json 객체를 가지고있다. 하나 또는 두 개의 오브젝트가 API의 일부 정보가 필요한 값을 가질 수 있습니다. 이 정보는 두 개의 오브젝트가 결합 된 것을 나타내는 레이블을 작성하는 데 사용됩니다.

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; 
}); 

원하는 조합 :

동적 레이블 (및 서비스 $의 HTTP 요청을 통해 라벨을 얻을 사이비 코드)와

var object1 = { 
    type: "some.type", 
    distribution: 50, 
    label: "Male" 
} 

대상 : 정의 된 라벨 (필요없는 조회)와

객체

var combinedObj = { 
    type: "some.type.combined", 
    distribution: 25, 
    // ideally label would be "Male > Alaska" 
    label: object1.label + " > " + object2.label 
    values: [object1, object2] 
} 

내 문제는 object2.label이 조합 obj 이후에 채워지지 않는다는 것입니다. ect가 생성되었습니다. 특히 레이블 문자열. 보기에서, 나는 "남자> 정의되지 않은"보고 있습니다. 나는 "남성> 68"까지 올 수 있었지만 실제로는 도움이되지 않습니다. 오브젝트를 결합하지 않을 때, 약속이 해결되면 레이블이 업데이트되고 두 개의 고유 항목으로 표시되는 "Alaska"와 "Male"을 가져 오는 데 문제가 없습니다. 두 레이블의 문자열을 결합하여 만들면 너무 빠르게 발생합니다.

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()이 올바른 값을 반환하더라도 실제 반환 값을 가져 오는 방법을 생각할 수 없습니다.

배열과 필터를 사용하여 문자열이 실제로 "마지막"이 될 때까지 실제로 만들지 않으므로 문자열이 "실제"가 아니므로 모델로 작동해야합니다. 마지막으로 업데이트 됨 (개체를 별도로 표시 할 때와 동일) :

그래서 여기에서 내가 무엇을 할 수 있는지 알아보기로했습니다. 그 문자열의 일부가 약속의 결과에 기반한 문자열을 만드는 방법은 무엇입니까? 나는 $ resource을 사용하면 label : labelResource를 설정할 수 있고 labelResource는 결국 내가 원하는 실제 데이터 (심지어 내가 원하는 데이터의 부모 객체도 도움이 될 것임)로 해석 될 것이라고 생각한다. 불행히도 $ resource에는 너무 복잡한 다른 논리가 있으므로 리팩터러가 없어도 사용할 수 없습니다. 나는 $ q.deferred.result와 같은 것으로 라벨을 설정할 수 있기를 바라고 있으며 (여전히 필터가 필요하더라도) 모든 것을 처리 할 수있다.

어쨌든, 고마워!

답변

1

당신은

https://docs.angularjs.org/api/ng/service/ $ q를 사용하면 $ Q를 찾을 수있는 페이지의 하단으로 이동 약속과 $ Q와 함께 할 수 있습니다.모두 기본적으로 문제에 대한 해결책입니다. 모든 약속이 해결되면 문자열 (레이블)에 가입하는 기능을 호출 할 수 있습니다.

+0

그래, 내가 그 앱의 다른 곳에서 해봤지만 문제는 서비스의 분리이다. 레이블에 대한 요청을 수행하는 서비스는 문자열 연결을 수행하는 서비스와는 별도의 서비스입니다. 그것에 대한 어떤 제안? ... 편집, 사실, 내가 생각을 가지고있을 수도 있습니다. – coblr

+0

두 서비스가 약속을 되 돌리면 여기서 문제가 발생하지 않습니다 :'여러 약속을 모든 약속이 해결되었을 때 해결되는 단일 약속으로 결합합니다 .' 그러므로'$ q.all (serviceOnePromise, serviceTwoPromise)'. 나는 해결책을 찾을 수있는 일하는 바이올린을 찾았습니다. http://jsfiddle.net/ThomasBurleson/QqKuk/ – maurycy

+0

Maurycy, 당신은 웅장한 놈입니다! 그것은 표이었다! 나는 그것을 작동 시키려면 조금 더 할 필요가 있었지만 그것이 내가 필요로하는 것이었다. 잠재적으로 많은 요청이 거의 동시에 실행되기 때문에 각 약속을 자체 이름으로 객체에 저장 한 다음 $ q.all()에 특정 약속을 대상으로 그 이름을 사용했습니다. 기다려야한다. 매력처럼 작동합니다! 건배!! BTW, 나는 최근에이 과거 월식의 사진 중 일부 이미지를 작성했으며 귀하의 아바타처럼 보입니다. https://www.flickr.com/photos/[email protected]/13867063614/ – coblr

0

여기에 언급 된 방법을 필터에서 확인해보십시오.

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.. 
} 

:>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]; 
    } 
    }); 

물론 테스트하지,하지만 뭔가를 시도 -

나는이 문제에 시작점으로 사용할 수있는 비동기 필터를 보여주는 간단한 바이올린을 만든 });

"라벨"이라는 약속은 매우 혼란 스러울 수 있으므로 코드를 재구성해야합니다. 그래야 소품 내부에 약속이있을 때 더욱 명확 해집니다.

행운을 빈다.

+0

이것은 너무 좋습니다. 나는 이것을 기술적으로 디스플레이하는 것이기 때문에 필터 처리라는 생각을 좋아하지만, 다른 답변보다 내 뇌를 감싸는 것이 좀 더 복잡합니다. 그래도 답변 주셔서 감사합니다! – coblr

+0

단순함이 항상 좋습니다! 건배 :) – GabrielG

관련 문제