2012-06-14 18 views
33

Estoy buscando la funcionalidad de desvinculación en knockout. Desafortunadamente, la búsqueda de Google y las preguntas que se hicieron aquí no me proporcionaron información útil sobre el tema.Desvincular el modelo de vista de la vista en knockout

Proporcionaré un ejemplo para ilustrar qué tipo de funcionalidad se requiere.

Digamos que tengo un formulario con varias entradas. También tengo un modelo de vista vinculado a este formulario. Por alguna razón, como reacción a la acción del usuario, debo desvincular mi modelo de vista del formulario, es decir, dado que la acción está completa, quiero que todos mis observables dejen de reaccionar en los cambios de los valores correspondientes y viceversa. Afecta los valores de las entradas.

¿Cuál es la mejor manera de lograr esto?

Respuesta

45

Puede usar ko.cleanNode para eliminar los enlaces. Puede aplicar esto a elementos DOM específicos o contenedores DOM de nivel superior (por ejemplo, el formulario completo).

Vea un ejemplo en http://jsfiddle.net/KRyXR/157/.

+2

brillante! ¡Gracias! – ILya

+2

la próxima vez que escriba getElementById y no $ ("# theid") [0] es mejor usar JavaScript y no jQuery para todo –

+18

Para proyectos en los que estoy usando jquery, generalmente me alegro de dar 1.5ms para evitar escribiendo 15 caracteres adicionales. Creo que me quedaré con los selectores de jquery cuando tenga la oportunidad. – Donamite

14

@Mark Robinson La respuesta es correcta.

Sin embargo, usando la respuesta de Mark hice lo siguiente, que puede serle útil.

// get the DOM element 
    var element = $('div.searchRestults')[0]; 
    //call clean node, kind of unbind 
    ko.cleanNode(element); 
    //apply the binding again 
    ko.applyBindings(searchResultViewModel, element); 
+0

+1 para ko.cleanNode (elemento) – lamarant

+0

Tuve que usar esto después de desactivar/habilitar manualmente los elementos de formulario para restaurar la automaticidad de los enlaces 'enable' de knockout. – casey

1

<html> 
 
    <head> 
 
     <script type="text/javascript" src="jquery-1.11.3.js"></script> 
 
     <script type="text/javascript" src="knockout-2.2.1.js"></script> 
 
     <script type="text/javascript" src="knockout-2.2.1.debug.js"></script> 
 
     <script type="text/javascript" src="clickHandler.js"></script> 
 
    </head> 
 
    <body> 
 
     <div class="modelBody"> 
 
      <div class = 'modelData'> 
 
       <span class="nameField" data-bind="text: name"></span> 
 
       <span class="idField" data-bind="text: id"></span> 
 
       <span class="lengthField" data-bind="text: length"></span> 
 
      </div> 
 
      <button type='button' class="modelData1" data-bind="click:showModelData.bind($data, 'model1')">show Model Data1</button> 
 
      <button type='button' class="modelData2" data-bind="click:showModelData.bind($data, 'model2')">show Model Data2</button> 
 
      <button type='button' class="modelData3" data-bind="click:showModelData.bind($data, 'model3')">show Model Data3</button> 
 
     </div> 
 
    </body> 
 
</html>

@ Marcos Robinson dio solución perfecta, no tengo problema similar con un solo elemento DOM y la actualización de los diferentes modelos de vista sobre este elemento DOM sola.

Cada modelo de vista tiene un evento de clic, cuando se hace clic, ocurre cada vez que se llama al método de cada modelo de vista, lo que provoca la ejecución innecesaria de bloques de código durante el evento de clic.

Seguí el enfoque de @Mark Robinson para limpiar el nodo antes de aplicar mis enlaces reales, realmente funcionó bien. Gracias Robin. Mi código de ejemplo es el siguiente.

function viewModel(name, id, length){ 
 
\t \t var self = this; 
 
\t \t self.name = name; 
 
\t \t self.id = id; 
 
\t \t self.length = length; 
 
\t } 
 
\t viewModel.prototype = { 
 
\t \t showModelData: function(data){ 
 
\t \t console.log('selected model is ' + data); 
 
\t \t if(data=='model1'){ 
 
\t \t \t ko.cleanNode(button1[0]); 
 
\t \t \t ko.applyBindings(viewModel1, button1[0]); 
 
\t \t \t console.log(viewModel1); 
 
\t \t } 
 
\t \t else if(data=='model2'){ 
 
\t \t ko.cleanNode(button1[0]); 
 
\t \t \t ko.applyBindings(viewModel3, button1[0]); 
 
\t \t \t console.log(viewModel2); 
 
\t \t } 
 
\t \t else if(data=='model3'){ 
 
\t \t ko.cleanNode(button1[0]); 
 
\t \t \t ko.applyBindings(viewModel3, button1[0]); 
 
\t \t \t console.log(viewModel3); 
 
\t \t } 
 
\t } 
 
\t } 
 
\t $(document).ready(function(){ 
 
\t \t button1 = $(".modelBody"); 
 
\t \t viewModel1 = new viewModel('TextField', '111', 32); 
 
\t \t viewModel2 = new viewModel('FloatField', '222', 64); 
 
\t \t viewModel3 = new viewModel('LongIntField', '333', 108); 
 
\t \t ko.applyBindings(viewModel1, button1[0]); 
 
\t }); 
 
\t

Cuestiones relacionadas