Puoi chiamare ko.applyBindings per associare una vista parziale?


258

Sto usando KnockoutJS e ho una vista principale e un modello di vista. Voglio che una finestra di dialogo (quella dell'interfaccia utente jQuery) venga visualizzata con un'altra vista a cui deve essere associato un modello di vista figlio separato.

L'HTML per il contenuto della finestra di dialogo viene recuperato utilizzando AJAX, quindi desidero essere in grado di chiamare ko.applyBindingsuna volta completata la richiesta e desidero associare il modello di visualizzazione figlio solo alla parte dell'HTML caricata tramite Ajax all'interno della finestra di dialogo div.

È effettivamente possibile o devo caricare TUTTE le mie visualizzazioni e visualizzare i modelli quando la pagina viene caricata inizialmente e quindi chiamare ko.applyBindingsuna volta?

Risposte:


431

ko.applyBindings accetta un secondo parametro che è un elemento DOM da utilizzare come root.

Questo ti permetterebbe di fare qualcosa del tipo:

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

Quindi, puoi usare questa tecnica per associare un viewModel al contenuto dinamico che carichi nella tua finestra di dialogo. Nel complesso, devi solo fare attenzione a non chiamare applyBindingspiù volte sugli stessi elementi, poiché avrai più gestori di eventi collegati.


17
Se si desidera rimuovere anche i collegamenti in qualche punto lungo la strada, è possibile chiamare ko.cleanNode(document.getElementById("one")per ripulire le cose o ko.removeNode(document.getElementById("one")per ripulire le cose e rimuovere il nodo dal DOM.
Michael Berkompas,

7
Solo una nota che cleanNodee removeNodenon rimuoverà i gestori di eventi, in modo da utilizzare una certa cautela. In alcuni casi, è preferibile utilizzare il binding templateo withsu quelle aree, in modo da visualizzare nuovi elementi.
RP Niemeyer,

7
Attualmente è qualcosa che manca a KO. Non intendiamo specificamente per le persone "ricollegare" le sezioni. Tuttavia, KO allega eventi usando jQuery, se è referenziato, quindi puoi fare $(element).unbind();per rimuovere tutti i gestori.
RP Niemeyer,

5
Dove sono documentate queste funzioni (applyBindings, cleanNode, removeNode)? Non riesco a trovare le firme delle loro funzioni su knockoutjs.com.
EricP,

2
Sarebbe bello se questo fosse da qualche parte facilmente individuabile all'interno della documentazione. Non ho nemmeno visto menzionarlo.
Travis Kaufman,

61

Mentre la risposta di Niemeyer è una risposta più corretta alla domanda, si potrebbe anche procedere come segue:

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

Ciò significa che non devi specificare l'elemento DOM e puoi anche associare più modelli allo stesso elemento, in questo modo:

<div>
  <input data-bind="value: VMA.name() + ' and ' + VMB.name()" />
</div>

4
puoi anche usare "con" per allocare le aree della pagina a singoli modelli - data-bind = "con: VMA"
lexicalscope

3
@flamingpenguin: Sì, ma withnon è economico, vedi: link
mhu

7

Sono riuscito a associare un modello personalizzato a un elemento in fase di esecuzione. Il codice è qui: http://jsfiddle.net/ZiglioNZ/tzD4T/457/

Il punto interessante è che applico l'attributo data-bind a un elemento che non ho definito:

    var handle = slider.slider().find(".ui-slider-handle").first();
    $(handle).attr("data-bind", "tooltip: viewModel.value");
    ko.applyBindings(viewModel.value, $(handle)[0]);

avendo problemi con ko 2.3, il codice sopra è in un gestore clienti che viene chiamato quando applico il ko.applyBindings globale (). Quindi ora viene visualizzato l'errore "Non è possibile applicare più associazioni allo stesso elemento". Sto ancora cercando di capire perché ricevo l'errore. Non possiamo applicare un'associazione alla stessa variabile più volte, ciascuno a elementi diversi?
ZiglioUK,

Ecco la versione con ko 2.3 che non funziona: jsfiddle.net/ZiglioNZ/tzD4T/458
ZiglioUK

Aggiungere una chiamata a ko.cleanNode () prima di chiamare applyBinding alla vista parziale non sembra aiutare: jsfiddle.net/ZiglioNZ/tzD4T/459
ZiglioUK

Risolto: non avevo nemmeno bisogno di chiamare applyBindings!
ZiglioUK,

Ho appena modificato il codice sorgente knockoutjs e commentato la parte in cui la funzione modifica "Non è possibile applicare più associazioni allo stesso elemento.", ora funziona tutto bene ... so che questa è una soluzione sporca ma sono nuovo nella libreria quindi non so come non applicarlo più volte per il mio problema.
Geomorillo,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.