Czy możesz wywołać ko.applyBindings, aby powiązać częściowy widok?

257

Korzystam z KnockoutJS i mam widok główny i model widoku. Chcę, aby okno dialogowe (interfejs jQuery) wyskakowało wraz z innym widokiem, z którym ma zostać powiązany oddzielny model widoku potomnego.

HTML dla zawartości okna dialogowego jest pobierany za pomocą AJAX, więc chcę móc zadzwonić ko.applyBindingspo zakończeniu żądania i chcę powiązać model widoku potomnego tylko z częścią HTML załadowaną za pośrednictwem ajax wewnątrz div okna dialogowego.

Czy to rzeczywiście możliwe, czy muszę ładować WSZYSTKIE moje widoki i modele widoków, gdy strona początkowo ładuje się, a następnie wywołuje ko.applyBindingsraz?

Charlie
źródło

Odpowiedzi:

430

ko.applyBindings akceptuje drugi parametr, który jest elementem DOM do użycia jako root.

To pozwoli ci zrobić coś takiego:

<div id="one">
  <input data-bind="value: name" />
</div>

<div id="two">
  <input data-bind="value: name" />
</div>

<script type="text/javascript">
  var viewModelA = {
     name: ko.observable("Bob")
  };

  var viewModelB = {
     name: ko.observable("Ted")
  };

  ko.applyBindings(viewModelA, document.getElementById("one"));
  ko.applyBindings(viewModelB, document.getElementById("two"));
</script>

Tak więc możesz użyć tej techniki, aby powiązać model viewModel z treścią dynamiczną ładowaną do okna dialogowego. Ogólnie rzecz biorąc, po prostu chcesz uważać, aby nie wywoływać applyBindingswiele razy w tych samych elementach, ponieważ otrzymasz wiele procedur obsługi zdarzeń.

RP Niemeyer
źródło
17
Jeśli chcesz również usunąć powiązania w pewnym momencie na drodze, możesz zadzwonić, ko.cleanNode(document.getElementById("one")aby wyczyścić rzeczy lub ko.removeNode(document.getElementById("one")wyczyścić rzeczy i usunąć węzeł z DOM.
Michael Berkompas
7
Uwaga: cleanNodei removeNodenie usunie programów obsługi zdarzeń, więc zachowaj ostrożność. W niektórych przypadkach lepiej jest użyć templatelub withwiązania na tych obszarach, aby renderować nowe elementy.
RP Niemeyer
7
Obecnie jest to coś, czego brakuje w KO. Nie zamierzamy specjalnie, aby ludzie „ponownie powiązali” sekcje. Jednak KO dołącza zdarzenia za pomocą jQuery, jeśli jest do nich odwołanie, więc możesz zrobić, $(element).unbind();aby usunąć wszystkie programy obsługi.
RP Niemeyer
5
Gdzie są udokumentowane te funkcje (applyBindings, cleanNode, removeNode)? Nie mogę znaleźć sygnatur funkcji na knockoutjs.com.
EricP,
2
Byłoby miło, gdyby było to gdzieś łatwo zlokalizować w dokumentacji. Nawet nie widziałem o tym wzmianki.
Travis Kaufman
61

Chociaż odpowiedź Niemeyera jest bardziej poprawna odpowiedź na pytanie, to mogłoby również wykonać następujące czynności:

<div>
  <input data-bind="value: VMA.name" />
</div>

<div>
  <input data-bind="value: VMB.name" />
</div>

<script type="text/javascript">
  var viewModels = {
     VMA: {name: ko.observable("Bob")},
     VMB: {name: ko.observable("Ted")}
  };

  ko.applyBindings(viewModels);
</script>

Oznacza to, że nie musisz określać elementu DOM i możesz nawet powiązać wiele modeli z tym samym elementem, jak poniżej:

<div>
  <input data-bind="value: VMA.name() + ' and ' + VMB.name()" />
</div>
mhu
źródło
4
możesz także użyć „z”, aby przydzielić regiony strony do poszczególnych modeli - data-bind = "with: VMA"
leksicalscope
3
@flamingpenguin: Tak, ale withnie jest tanie, patrz: link
mhu
7

Udało mi się powiązać niestandardowy model z elementem w czasie wykonywania. Kod jest tutaj: http://jsfiddle.net/ZiglioNZ/tzD4T/457/

Interesujące jest to, że stosuję atrybut wiązania danych do elementu, którego nie zdefiniowałem:

    var handle = slider.slider().find(".ui-slider-handle").first();
    $(handle).attr("data-bind", "tooltip: viewModel.value");
    ko.applyBindings(viewModel.value, $(handle)[0]);
ZiglioUK
źródło
mam problem z ko 2.3, powyższy kod znajduje się w module obsługi klienta, który jest wywoływany, gdy zastosuję globalną ko.applyBindings (). Tak więc teraz pojawia się błąd „Nie można zastosować powiązań wiele razy do tego samego elementu.”. Nadal próbuję dowiedzieć się, dlaczego pojawia się błąd. Czy nie możemy zastosować wiązania do tej samej zmiennej wiele razy, każdy do różnych elementów?
ZiglioUK
Oto wersja z ko 2.3, która nie działa: jsfiddle.net/ZiglioNZ/tzD4T/458
ZiglioUK
Dodanie wywołania do ko.cleanNode () przed wywołaniem applyBinding do widoku częściowego nie wydaje się pomocne: jsfiddle.net/ZiglioNZ/tzD4T/459
ZiglioUK
Rozwiązane: Nie musiałem nawet dzwonić z aplikacją Wiązania!
ZiglioUK
właśnie dokonałem edycji kodu źródłowego knockoutjs i skomentowałem część, w której funkcja rzuca: „Nie można wielokrotnie przypisywać powiązań do tego samego elementu.”, teraz wszystko działa dobrze ... wiem, że to brudne rozwiązanie, ale jestem nowy w bibliotece, więc nie wiem, jak nie stosować go wiele razy dla mojego problemu.
Geomorillo,