2013-09-05 1 views
1

여기서는 속성 바인딩 (attr)을 사용해야하는 시나리오가 있지만 적용 할 실제 값은 콜백을 통해 반환되므로 녹아웃을 얻는 방법은 콜백 인식이 될 수 있습니까?비동기 함수로 녹아웃 바인딩 대상

대답은 '아니오'라고 가정하고 비동기 녹아웃 플러그인 중 하나를 사용해야하지만 그 중 일부는 더티 플래그 등 설정이 필요하기 때문에 그 모델을 복잡하게 만들지는 않을 것입니다. 그래서 여기

코드 예제 : 위의 예에서

function SomeViewModel() 
{ 
    var someStorageMechanism = new StorageMechanism(); 

    this.GetUserPicture = function(userId) { 
     someStorageMechanism.GetUserData(userId, function(userData) { 
      // should really be using a callback argument then do callback(userData.picture); but knockout has no notion of this 
     }); 
    }; 
} 

<img data-bind="attr: { src: GetUserPicture($data.userId) }"/> 

GetUserPicture 이상적으로 이미지 데이터 문자열 또는 URL, 그러나 데이터가 기본 개체에서이 경우에 검색 할 필요를 반환해야하는 비동기 적으로 작동하므로이 문제를 해결할 수있는 간단한 방법이 있습니까?

+2

왜 viewmodel에서 관찰 가능 속성 인'picture'를 만들지 않습니까? 그런 다음 바인딩 ''에서 해당 속성을 사용할 수 있으며 콜백에서'this.picture (userData.picture) '로 값을 설정하면 뷰 모델 내부에서'GetUserPicture (userId)'를 호출 할 수 있습니다. – nemesv

+0

약속을 들었습니까? https://github.com/knockout/knockout/wiki/Use-an-observable-as-a-jQuery-promise 비동기 데이터를 처리하는 한 가지 방법입니다. –

+0

@nemesv이 시나리오는 foreach (템플릿이 ko 외부 템플릿 로더를 사용하는 비동기식) 인 템플리트입니다.이 중 하나의 섹션에는 속성을 설정해야하므로 각 항목에는 자체 그림이 있지만 그림은 저장됩니다 localStorage 영역 내에서. 그래서이 데이터를 각각의 항목에서 관찰 할 수있게하려면 foreach 내에있는 각 항목을 미리 처리하고 각각의 그림을 미리 채우거나 afterRender를 기다린 다음 수행해야합니다. ,하지만 그 큰 그림의 아주 작은 부분에 대한 여러 장소에서 훨씬 더 많은 논리가 – Grofit

답변

2

"is there any way to get knockout to somehow become callback aware?"

예, 서브 스크립 션을 사용할 수 있습니다. 이 작업을 수행 할 수 있도록 모든 관찰 가능한, observableArrays 및 computeds는 형식 등록 가능 상속 : 당신도 일시적으로 구독을 설정하고 더 이상 필요하지 않은 나중에 취소 할 수 있습니다 구독

var foo = ko.observable("foo"); 
foo.subscribe(function (newValue) { 
    // When foo updates, this function is called 
}); 

.

var fooSub = foo.subscribe(function (newValue) { 
    // When foo updates, this function is called 
}); 
// Somewhere else in the app... 
fooSub.dispose(); 

기본적으로 구독은 '변경'이라는 주제에 가입합니다. 즉, 관찰 가능 항목의 값이 변경되면 newValue (즉 매개 변수 이름)를 가진 구독자를 호출하지만 일부 값 앞에 논리를 수행하기 위해 'beforeChange'주제에 가입하는 구독을 설정할 수도 있습니다 변경.

foo.subscribe(function (oldValue) { 
    // Do logic on the oldValue here 
}, null, 'beforeChange'); 

그리고 knockout의 documentation에서 읽을 수 있습니다. 원하는 경우 맞춤 주제에 가입 할 수도 있습니다. 기본적으로 관찰 가능 값이 변경되면 'beforeChange'및 'change'주제가 값 변경 전후에 실행됩니다. 그러나 나중에 수동으로 트리거 할 수있는 사용자 지정 항목을 구독하여 해당 항목을 수신하는 모든 구독자에게 알릴 수 있습니다.

foo.subscribe(function (value) { 
    // Do logic when observable notifies subscribers to the 'customTopic' topic 
}, null, 'customTopic'); 

// Somewhere else in the app... 
var value = "bar"; 
foo(value); 
foo.notifySubscribers(value, 'customTopic'); 

이렇게하면 서로 직접적인 참조가없는 별도의보기 모델간에 통신을 설정할 수 있습니다. 이것은 어떻게하는지에 대한 이해를 돕기위한 것입니다. Ryan Niemeyer의 팁과 트릭을보고 더 자세히 알 수 있습니다. video. 특히 구독 섹션.

이렇게하면 녹아웃에서 일종의 콜백을 수행 할 수 있습니다. 또한 관찰 가능 항목을 subscribeTo 및 publishOn으로 확장하는 Ryan의 Knockout-postbox 라이브러리를 확인하십시오.


또한 $ 아약스 요청을 사용하는 기본 조각 jQuery를 $.Deferreds로 볼 수있다. 녹아웃 콜백은 아니지만 일종의 콜백입니다.

내가 원하는 것을 더 많이 알려주시겠습니까?

+0

기본적으로 관찰 가능한 배열에 데이터를 캐시해야하는 약간의 해킹이 느껴집니다. 가장 좋은 해결책은 (비동기 바인딩을 사용하지 않고 사람들에게 원래의 질문을 생각 나게하는 것입니다), 런타임에 속성을 그림을 저장하는 객체에 첨부하는 것입니다. 따라서 Ajax 바인딩이 필요하지 않습니다. 또한 비동기 비트가 localstorage lookup 인 시나리오에서 명확히하기 위해 유스 케이스를 단순화 할 서버 측 구성 요소 나 아약스 요청이 없습니다. – Grofit

+0

나를 우려하는 것은 코드의 냄새입니다. 누군가가''과 같은 것을 보게 될 때입니다. 이벤트 핸들러는 어딘가에서 관찰 가능한 값을 설정해야하거나 바인딩에 계산이 사용되어야하는 것처럼 들립니다. 내 대답을 업데이트 할 수있는 몇 가지 옵션이 있습니다. – nwayve

+0

관찰 가능이라는 것은 뷰 모델과 UI 사이의 2 방향 바인딩을 의미합니다. 따라서 UI에서 변경 될 때 업데이트하고 싶은 것이 있습니다. 항상 그런 것은 아니지만 대부분의 경우입니다. 그러나이 예제에서는 업데이트되는 것이 아니며, 템플릿이 렌더링 된 다음 잊어 버렸을 때 한 번 설정되므로 기본적으로 읽기 전용 값을 캐시하는 관찰자를 설정하는 오버 헤드가 무의미 해 보입니다. 이것에 적용된 비즈니스 로직이 없기 때문에 난처한 비즈니스 관심사가 아니므로 걱정하지 않아도됩니다. – Grofit