2012-03-01 23 views
7

Mam szybkie pytanie dotyczące customBindings, mam nadzieję, że niektóre mogą mi pomóc wyjaśnić? Pomyślałem, że gdy obserwowalne zostanie zaktualizowane, że wszelkie niestandardowe powiązanie, które jest związane z tym obserwowalnym, zostanie wywołana metoda "aktualizacji". Widzę, że po aktualizacji zauważam, że powiadamiani są inni subskrybenci, ale nie wygląda na to, że wywoływana jest funkcja customBinding.Knockout + customBinding nie aktualizuje

Oto mój ViewModel:

var innerModel = { 
    name: ko.observable('junk') 
}; 

var innerModel2 = { 
    name: ko.observable('junk2') 
}; 

var viewModel = { 
    im1: innerModel, 
    im2: innerModel2, 
    selectedModel: ko.observable({name:'xxx'}) 
}; 

i tu jest moje customBinding:

ko.bindingHandlers.custom = { 
    update: function(element, valueAccessor) { 
     console.log("BAM!"); 
     while (element.firstChild) 
      ko.removeNode(element.firstChild); 

     ko.renderTemplate('test', valueAccessor(), {}, element, 'replaceNode'); 

    } 
}; 

gdzie mój szablon jest po prostu okres, który wyświetla "nazwa" murawę:

<script id='test' type='text/html' charset='utf-8'> 
<span data-bind='text: name'></span> 
</script> 

Oto kod HTML, którego używam w powiązaniu niestandardowym:

<div id="container" data-bind="with: viewModel"> 
    <div data-bind="custom: selectedModel"> 
    </div> 
</div> 

Po zaktualizowaniu wybranego modelu do jednego z dwóch modeli innerModels wyświetlana jest poprawna nazwa, ale funkcja "update" customBinding nie jest wywoływana. Mam oddzielny abonenta do „selectedModel” obserwowalny:

viewModel.selectedModel.subscribe(function(newValue) { 
    console.log(newValue.name()); 
}); 

i że nazywa się przy zmianie selectedModel, więc dlaczego nie aktualizuje customBinding jest nazywany?

Oto jsfiddle który pokazuje problem: http://jsfiddle.net/gperng/twAcJ/

Każda pomoc będzie mile widziana!

Odpowiedz

0

Twoje użycie with jest w tym przypadku nieprawidłowe. Jeśli korzystasz z tego, że to zadziała zgodnie z oczekiwaniami:

<div id="container" data-bind="with: selectedModel"> 
    <div data-bind="custom: $data"> 
    </div> 
</div> 

To dlatego, że w przykładzie custom wiązanie nie jest na selectedModel, ale na całej samego viewmodel, który nie zmienia się.

Oto jsfiddle niego: http://jsfiddle.net/soniiic/twAcJ/7/

+1

nie jestem 100% to ma sens. Jeśli wyjmę element div z powiązaniem "with", nadal napotykam na ten sam problem, co poprzednio (gdzie program obsługi zmian wiązania niestandardowego nie jest wywoływany, mimo że zmienna obserwowalna została zmieniona). W twoim przykładzie "init" niestandardowego powiązania jest wywoływany za każdym razem (ponieważ obiekt macierzysty jest obserwowalny i się zmienił, więc wszystkie poniższe elementy podrzędne są ponownie renderowane). Zobacz http://jsfiddle.net/gperng/6nw8B/, dodałem funkcję "init" i widać, że wiązanie jest ponownie inicjowane za każdym razem. –

9

Musisz wywołać następującą funkcję, aby to działało:

var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor()) 

Spróbuj skrzypce na więcej: http://jsfiddle.net/twAcJ/13/

+0

To właściwie nie działa dla mnie. Drukuje tylko "BAM!" raz, nigdy. Pomimo wielokrotnego naciskania wszystkich przycisków. Zauważ, że wybrałem nokaut 3.0.0 (chociaż 2.3.0 też nie działa). – Aktau