cuando me inyecte nuevos elementos en el DOM después de ko.applyBindings(); fue llamado, entonces knock-out no reconocer estos nuevos elementos.
Puedo entender por qué esto está sucediendo – que no son indexados por los octavos de final.

Así, al principio pensé que esto sería resuelto con sólo una llamada al ko.applyBindings() de nuevo, después de la adición de mis nuevos elementos, PERO luego me di cuenta de que por cada ko.applyBindings() llamada, la función de los eventos se desencadena varias veces. Así que después de la aplicación de cinco veces, haga clic en: enlace se disparó cinco veces, así que esta no es una solución deseable 😉

Hay nada como ko.updateBindings() o algo más, para decirle a los octavos de final a, bueno… actualizar el elemento de enlaces?

saludos,
Chris

  • Puedes publicar algo de código para mostrar lo que estás haciendo?
  • así, por ejemplo algo como esto: $(‘body’).append(‘<a href=»#» data-bind=»haz clic en «algo»>haga Clic en me!</a>’);
  • No estoy seguro de que es el contexto suficiente para proporcionar una respuesta útil. Entiendo lo que usted está tratando de hacer, pero con una imagen más completa de su código (por qué/cuando la inyección de nuevos elementos DOM) es difícil de responder con la mejor manera de cuidar de esto. Podría ser, después de mirar su solución actual, que alguien pueda señalar un camino para no tener que inyectar los nuevos elementos o tiene una solución para lo que estamos tratando de hacer.
  • Me parece que se han encontrado. Con sólo llamar a: ko.applyBindings(viewModel); de nuevo se une a todas las funciones de nuevo a toda la DOM. Esta es la razón, cada callback es llamado dos veces y más después de volver a llamar a esta función. El segundo parámetro para applyBindings() es un nodo DOM para empezar a aplicar a partir de. Por defecto, este será el DOM de la raíz. Por lo tanto, si usted está agregando un par de elementos con enlazar los datos de los atributos de «manualmente» a algunos nodo DOM, agarra una referencia al nodo DOM con los nuevos elementos y pasar como segundo parámetro!
  • Impresionante! Me olvidé de la segunda parm para applyBindings().

3 Comentarios

  1. 36

    Cada vez que se invoca ko.applyBindings toda la DOM es inspeccionado para los enlaces. Como resultado, se obtendrá varios enlaces para cada elemento si hacer esto más de una vez. Si sólo quieres enlazar un nuevo elemento de DOM puede pasar este elemento como un parámetro para la applyBindings función:

    ko.applyBindings(viewModelA, document.getElementById("newElement"));

    Ver esta pregunta relacionada con:

    Puede usted llamar a ko.applyBindings para enlazar una vista parcial?

    • Sí, esa es la solución que se me ocurrió, también 🙂 Lamentablemente no he encontrado un directo a la documentación de la API en knockoutjs.com y tenía que hacer algo de ingeniería inversa en el ko objeto para averiguar esto -.-
    • Cierto, no es ninguna documentación de la API, pero es en el más ‘prolijo’ documentación. Mira a mitad de camino hacia abajo en esta página: knockoutjs.com/documentation/observables.html
    • Está usted seguro de que esta es la respuesta? No se puede aplicar esto viewModelA a la newElement como si newElement es la raíz de la DOM para viewModelA? Puedo ver donde iba a funcionar una parte o incluso la mayoría de las veces, pero también puedo ver cómo podría ser producto unexpeced resultados (creo).
    • Yo sólo pensé que comentar aquí, ya que en realidad se tropezó con una de gotcha. Yo estaba cargando niño vistas por ajax y pegándolos en el modelo de vista que estaba destinado a la vista para colocar niño (parcial) vistas en el lugar correcto en la página principal. Uno debe ser muy cuidado con qué elementos se unen. Yo estaba descuidadamente llamar applyBindings para el elemento que se celebró la vista parcial, que por todas las apariencias de la causa para volver a cargar la vista parcial. He tenido que cambiar la lógica para seleccionar a los niños de ese elemento, o en otras palabras, la totalidad de la vista parcial.
    • «Mientras que los nodos no compartir parte del árbol (por ejemplo, son hermanos) usted puede llamar a applyBindings de manera segura en cada uno de los nodos (de hecho, esa es una razón para usar el segundo argumento).»
  2. 7

    Sin saber que es lo que hacen exactamente, parece que te estás yendo por el camino equivocado acerca de esto. Su punto de vista debe ser impulsado por el modelo de vista. Entonces usted no debería estar directamente la adición de elementos DOM deberá aplicar knockout enlaces.

    Lugar usted debe actualizar su modelo de vista para reflejar el cambio en la vista, lo que provoca su nuevo elemento a aparecer.

    Así, por ejemplo, para su $('body').append('<a href="#" data-bind="click: something">Click me!</a>');, en lugar de agregar el elemento de DOM cuando el botón debe ser visible, de control el botón de visibilidad mediante el modelo de vista.

    Por lo que su modelo de vista incluye

    var viewModel = { clickMeAvailable: ko.observable(false) }

    Y su HTML incluye

    <a href="#" data-bind="click: something, visible: clickMeAvailable">Click me!</a>

    Cuando el estado de la aplicación de los cambios por lo que el me haga clic en el botón está disponible, sólo viewModel.clickMeAvailable(true).

    El punto de hacerlo, y una gran parte de knock-out, es separar la lógica de negocio de la presentación. Así, el código que hace que me haga clic en disponible no le importa que haga clic en me implica un botón. Todo lo que hace es actualizar viewModel.clickMeAvailable cuando haga clic en mí está disponible.

    Por ejemplo, digamos que me haga clic en un botón de guardar que debe estar disponible cuando un formulario es llenado en válidamente. Que había atar el botón guardar visibilidad a un formValid modelo de vista observable.

    Pero luego decide cambiar las cosas para que después de que el formulario es válido, un acuerdo legal parece que tiene que ser consentido antes de guardar. La lógica de su forma no cambia – todavía marca formValid cuando el formulario es válido. Usted acaba de cambiar lo que ocurre cuando formValid cambios.

    Como lassombra señala en los comentarios de esta respuesta, hay casos cuando directa de manipulación DOM puede ser el mejor enfoque – por ejemplo una dinámica compleja en la página donde desea que sólo para hidratar partes de la vista a medida que se necesitan. Pero se están dando algunos de la separación de los intereses knock-out proporciona al hacer esto. Ser conscientes de si usted está considerando la posibilidad de hacer este trade-off.

    • Mientras que ciertamente estoy de acuerdo con todo esto, creo que hay momentos en que tiene sentido para aprovechar knockoutjs en una manera que terminan con «anidada» modelos de vista. Esto podría ser más a lo largo de las líneas de la situación en la que Cristiano estaba tratando. En cuyo caso usted debe tener un modelo de vista que se creó específicamente para y someterse a su anidada HTML (presumiblemente tirado en la vía ajax) cuando está disponible o se ha terminado de cargar.
    • Para el registro, creo que esta es la respuesta correcta. El control debe ser limitados en la declaración, no expulsados del evento comportamiento. Knockout es una de esas tecnologías donde usted necesita para mantener el enfoque consistente para evitar los molestos errores al mínimo.
    • Lo que sobre todo los sitios grandes donde la vista está cambiando? Deben todos los posibles puntos de vista se empaquetan en la página predeterminada? Seguramente no. Carga de una vista a través de ajax transición a otras «áreas» de que el sitio es sin duda una práctica aceptable (yo personalmente estoy usando esto en una aplicación web que me estoy convirtiendo. La aplicación original es MVC4 y tiene diferentes puntos de vista de diferentes personal de administración de datos, yo estaba de seguimiento (acciones, otras finanzas, lista de tareas, lista de contactos, calendario de eventos). Ya que todos ellos utilizan la misma página principal, la conversión de ellos a MVVM/knock-out es bastante sencillo.
    • Que una feria llamada, no hay ningún «verdadero camino». Pero si vas a empezar directa de manipulación DOM, esto debe ser una decisión deliberada, sabiendo que usted está operando fuera de la separación de los intereses knock-out proporciona. Como digo en mi respuesta, «Sin saber que es lo que hacen exactamente». He editado para reflejar tu comentario, aunque.
  3. 0

    Sé que usted pidió hace mucho tiempo, pero me topé con un problema similar. He intentado añadir nuevos elementos en el contenedor y dar a los que una función onclick.
    En primer lugar, trató de las cosas que hizo, e incluso trató el enfoque ColinE recomendado. Esto no era una solución práctica para mí, así que he intentado SamStephens enfoque y vino para arriba con eso, que workes a la perfección 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 ella en el JS Violín he hecho.
    Espero que esto ayuda a alguien.

    • Bueno, para mí… he abandonado KnockoutJS hace mucho tiempo ya que era demasiado unflexible para mis propósitos.
    • KO es casi inflexible .. algunas cosas se deben hacer KO manera (todavía tengo que encontrar una necesidad para cambiar el enlace!) para ser agradables, pero Durandal (que utiliza KO) -> una increíble flexibilidad con soporte para vistas – vistas independientes mitigar efectivamente el manual de intentar parcialmente enlace como cada vista puede introducir cualquiera de presentar su propio modelo o compartir [parte de] un modelo. Ahora, hay un par de cosas acerca de KO no me gusta, pero no tiene nada que ver con la falta de flexibilidad! De la observación del modelo es es flexible a la vez es utilizado plenamente.
    • El «hackish pero fácil» de manejar al azar (externo) elementos inyectados en la DOM, para insertarlos en un control de flujo enlace como if (este post se muestra foreach que es sin duda el limpiador para empezar) y, a continuación, cambiar el contenido «on» después de que los elementos se insertan – el nuevo subárbol sólo se unen, según corresponda. Hay sin extra manual applyBindings y un observable controla el flujo de unión. Adicional enlaces como withProperties puede ser usada para refinar las propiedades en el ámbito.

Dejar respuesta

Please enter your comment!
Please enter your name here