javascript - multiple - knockout.js: ¿enlaces de actualización?
value knockout js (3)
cuando inyecto cualquier elemento nuevo en el DOM después de ko.applyBindings (); fue llamado, entonces knockout no reconocerá estos nuevos elementos. Puedo entender por qué está sucediendo esto: simplemente no están indexados por nocaut.
Entonces, al principio pensé que esto se resolvería simplemente llamando a ko.applyBindings () de nuevo, después de agregar mis nuevos elementos, PERO luego me di cuenta de que por cada llamada de ko.applyBindings () que realizas, los eventos correspondientes se activan varias veces. Entonces, después de aplicar cinco veces, un clic: el enlace se disparará cinco veces, por lo que esta no es una solución deseable;)
¿Hay algo como ko.updateBindings () o algo más, para decirle a knockout, bueno ... actualizar los enlaces de los elementos?
saludos, Chris
Sé que lo preguntaste hace mucho tiempo, pero me topé con un problema similar. Traté de agregar nuevos elementos al contenedor y otorgarles una función onclick. Al principio probé las cosas que hizo, e incluso probé el enfoque recomendado por . Esta no fue una solución práctica para mí, así que probé el enfoque de y se me ocurrió eso, que funciona perfectamente para mí:
HTML:
<div id="workspace" data-bind="foreach:nodeArr, click:addNode">
<div class="node" data-bind="attr:{id:nodeID},style:{left:nodeX,top:nodeY},text:nodeID, click:$parent.changeColor"></div>
</div>
JavaScript:
<script>
function ViewModel() {
var self = this;
var id = 0;
self.nodeArr = ko.observableArray();
self.addNode = function (data, event) {
self.nodeArr.push({
''nodeID'': ''node'' + id,
''nodeX'' : (event.offsetX - 25) + ''px'',
''nodeY'' : (event.offsetY - 10) + ''px''
})
id++;
}
self.changeColor = function(data, event){
event.stopPropagation();
event.target.style.color = ''green'';
event.target.style.backgroundColor = ''white'';
}
}
ko.applyBindings(new ViewModel());
</script>
Puedes jugar con él en el JS Fiddle que hice. Espero que esto todavía ayude a alguien.
Sin saber exactamente qué tramas, parece que vas por el camino equivocado al respecto. Su punto de vista debe ser impulsado por su modelo de vista. Por lo tanto, no debería agregar elementos DOM directamente, luego debe aplicar enlaces knockout.
En su lugar, debe actualizar su modelo de vista para reflejar el cambio en la vista, lo que hace que aparezca su nuevo elemento.
Por ejemplo, para su $(''body'').append(''<a href="#" data-bind="click: something">Click me!</a>'');
, en lugar de agregar el elemento DOM cuando el botón debería estar visible, controle la visibilidad del botón utilizando el modelo de vista.
Entonces su modelo de vista incluye
var viewModel = { clickMeAvailable: ko.observable(false) }
Y tu HTML incluye
<a href="#" data-bind="click: something, visible: clickMeAvailable">Click me!</a>
Cuando el estado de la aplicación cambia para que el botón "hacer clic en" esté disponible, simplemente viewModel.clickMeAvailable(true)
.
El objetivo de hacer esto, y una gran parte de nocaut, es separar la lógica de negocios de la presentación. Entonces, el código que hace que haga clic en me esté disponible no importa que hacer clic en mí involucre un botón. Todo lo que hace es actualizar viewModel.clickMeAvailable
cuando haga clic en Me está disponible.
Por ejemplo, digamos "clic en mí" es un botón de guardar que debería estar disponible cuando un formulario se rellena de manera válida. formValid
vincular la visibilidad del botón de guardar a un modelo de vista de formValid
observable.
Pero luego decides cambiar las cosas, así que después de que el formulario sea válido, aparece un acuerdo legal al que se debe dar su consentimiento antes de guardarlo. La lógica de su formulario no cambia; todavía establece formValid
cuando el formulario es válido. Simplemente cambiaría lo que ocurre cuando cambia formValid
.
Como señala lassombra en los comentarios sobre esta respuesta, hay casos en los que la manipulación directa del DOM puede ser su mejor enfoque, por ejemplo, una página dinámica compleja en la que solo desea hidratar partes de la vista a medida que se necesitan. Pero estás abandonando parte de la separación de las preocupaciones que proporciona Knockout al hacer esto. Tenga en cuenta si está considerando realizar esta transacción.
Cada vez que ko.applyBindings
se inspecciona todo el DOM en busca de enlaces. Como resultado, obtendrá enlaces múltiples para cada elemento si hace esto más de una vez. Si solo desea vincular un nuevo elemento DOM, puede pasar este elemento como un parámetro a la función applyBindings
:
ko.applyBindings(viewModelA, document.getElementById("newElement"));
Ver esta pregunta relacionada:
¿Puedes llamar a ko.applyBindings para vincular una vista parcial?