multiple knockout for data knockout.js knockout-components

knockout.js - for - knockout select value binding



¿AfterRender funciona con componentes Knockout? (3)

afterRender funciona con enlaces de plantilla, pero después de convertir mis plantillas a componentes, no parece haber ninguna forma de usar afterRender . Intenté buscar un ejemplo de un componente que utiliza afterRender , pero no puedo encontrar nada.


El secreto aquí es http://knockoutjs.com/documentation/custom-bindings.html

ko.bindingHandlers.myCustomBinding = { init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { // This will be called when the binding is first applied to an element // Set up any initial state, event handlers, etc. here if (bindingContext.$data.init) bindingContext.$data.init(element, valueAccessor, allBindings, viewModel, bindingContext); }, update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { // This will be called once when the binding is first applied to an element, // and again whenever any observables/computeds that are accessed change // Update the DOM element based on the supplied values here. if (bindingContext.$data.update) bindingContext.$data.update(element, valueAccessor, allBindings, viewModel, bindingContext); } };

entonces en mi plantilla de componente hago algo como

<div class="row-fluid" data-bind="myCustomBinding: ''someValue''">

y en el componente viewModel acabo de implementar init y / o update, por ejemplo:

constructor.prototype.init = function(element, valueAccessor, allBindings, viewModel, bindingContext) { // All the buttons in the buttons group need the same name, // but they all need distinct ids. We use timestamps because // as components, the names and ids should be distinct across // multiple instances of each component. var timeStamp = new Date().getTime(); $(''input:radio'').attr(''name'', timeStamp).button(); $(''input:radio:eq(0)'').attr(''id'', timeStamp+1); $(''input:radio:eq(1)'').attr(''id'', timeStamp+2); $(''input:radio:eq(2)'').attr(''id'', timeStamp+3); // Initialize the number-picker $(''input[name="number-picker"]'').TouchSpin(); };

La documentación de Knockout podría mejorarse señalando este caso tan útil. Además, este es un enlace tan útil, debería haber un enlace estándar para ''init'' y ''update'', por ejemplo

<div data-bind="init: ''someValue''">


Necesitábamos acceder a los elementos DOM en un componente después de cambiar entre diferentes componentes. Nos hubiera gustado utilizar el enlace "afterRender" no existente en los componentes.

Lo solucionamos con un Javascript setTimeout, lo que permite a KO hacer primero su renderizado y, de hecho, poner en cola nuestro código después de eso.

HTML:

<div data-bind="component: compName"></div>

El código que cambia el componente:

var compName = ko.observable(); //... compName(switchToComponent); setTimeout(function(){ // this code is queued until after the component is rendered. }, 0);


No pude hacer que el método funcionara de acuerdo con la publicación anterior. Sin embargo, encontré una solución alternativa en la lista de problemas de git y no requiere un enlace de KO personalizado.

Agregue la siguiente línea en la plantilla de su componente html o cadena de código.

<span data-bind="template: { afterRender: init }"></span>

Luego crea una función init en tu módulo / viewModel:

this.init = function() { Do cool DOM stuff here. }

o dependiendo de su estructura viewModel:

viewModel: function(params) { return { init: function () { } }; },

Funciona de maravilla. Ejemplo de que está funcionando aquí

http://jsfiddle.net/gLcfxkv6/1/

Hilo sobre git knockout aquí: https://github.com/knockout/knockout/issues/1533

Gracias a los vampiros en git por la solución.