knockoutjs knockout data javascript binding knockout.js observable

javascript - data - Knockoutjs calculó los parámetros de paso



knockout js lifecycle (4)

Crea una función cuyo único propósito es devolver un observable calculado. Puede tomar los parámetros que desee. Tendrá que ser un observable calculado separado si desea que sea un enlace bidireccional.

Luego, en su enlace, llame a esa función con los argumentos apropiados. El observable calculado que devuelve estará vinculado a su vista y se actualizará como de costumbre.

Aquí hay un violín donde utilicé esta técnica para crear controladores de eventos. Puedes hacer algo similar aquí.

Puedes mantenerlo limpio haciendo que la función sea un método en lo observable. Al agregar al prototipo ko.observable.fn o agregarlo directamente a la instancia observable.

ko.observable.fn.bit = function (bit) { return ko.computed({ read: function () { return !!(this() & bit); }, write: function (checked) { if (checked) this(this() | bit); else this(this() & ~bit); } }, this); }; // or function ViewModel() { this.flags = ko.observable(0); this.flags.bit = function (bit) { return ko.computed({ read: function () { return !!(this() & bit); }, write: function (checked) { if (checked) this(this() | bit); else this(this() & ~bit); } }, this); }.bind(this.flags); }

Luego aplica a tu vista

<input type="checkbox" data-bind="checked: flags.bit(0x1)"/> <input type="checkbox" data-bind="checked: flags.bit(0x2)"/> <input type="checkbox" data-bind="checked: flags.bit(0x4)"/> <input type="checkbox" data-bind="checked: flags.bit(0x8)"/>

Demo

Sin embargo, si solo intenta vincular todas las casillas de verificación a un solo valor en su modelo de vista, no necesita hacer eso. Utilice el enlace checked en una matriz en su modelo de vista y dé un valor a sus casillas de verificación. Cada valor verificado se agregará a la matriz. Y será un enlace bidireccional.

<input type="checkbox" data-bind="checked: checkedValues, value: 1"/> <input type="checkbox" data-bind="checked: checkedValues, value: 2"/> <input type="checkbox" data-bind="checked: checkedValues, value: 3"/> <input type="checkbox" data-bind="checked: checkedValues, value: 4"/>

var viewModel = { checkedValues: ko.observableArray([]) };

Demo

Me pregunto si es posible con knockoutjs pasar argumentos cuando se enlace.

Estoy vinculando una lista de casillas de verificación y me gustaría enlazar a un solo observable calculado en mi modelo de vista. En mi modelo de vista (basado en el parámetro pasado a la función de lectura) quiero devolver verdadero / falso según ciertas condiciones.

var myViewModel=function(){ this.myprop=ko.computed({read: function(){ //would like to receive an argument here to do my logic and return based on argument. } }); }; <input type="checkbox" data-bind="checked: myprop(someval1)" /> <input type="checkbox" data-bind="checked: myprop(someval2)" /> <input type="checkbox" data-bind="checked: myprop(someval3)" />

¿Alguna sugerencia?


La respuesta aceptada es decente, pero si tiene una función que genera un ko.computado para cada casilla de verificación, está agregando una sobrecarga innecesaria con múltiples observables calculados anónimos, que se acumula rápidamente cuando las listas de casillas de verificación exceden de 4 a 5 opciones.

Esta es una implementación más simple de un escenario bit a bit, pero la función calculada puede ser lo que sea necesario.

<input type="checkbox" data-bind="checked: checkedList, value: 1" /> <label>Value 1</label> <input type="checkbox" data-bind="checked: checkedList, value: 2" /> <label>Value 2</label> <input type="checkbox" data-bind="checked: checkedList, value: 4" /> <label>Value 4</label> <input type="checkbox" data-bind="checked: checkedList, value: 8" /> <label>Value 8</label>

Guión:

var vm = function() { var vm = this; this.checkedList = ko.observableArray(); this.bitwiseValue = ko.computed({ read: function () { return vm.checkedList().reduce(function (prev, curr) { return prev | curr; }, 0); }, write: function (myVal) { vm.checkedList.removeAll(); var placeValue = 1; while(myVal > 0) { if((myVal % 2) == 1) { alert(placeValue); vm.checkedList.push(placeValue.toString()); } myVal = myVal >>> 1; placeValue = placeValue * 2; } } }, this); } ko.applyBindings(vm);

Ejemplo de violín aquí: http://jsfiddle.net/i_vargas3/RYQgg/


No hay ninguna razón para usar un valor computed . Simplemente defina una función en su Modelo de Vista y vincule la checked a ella.

A continuación se muestra un ejemplo muy simplista.

-

HTML

<input type="checkbox" data-bind="checked: isEven(1)" /> <input type="checkbox" data-bind="checked: isEven(2)" /> <input type="checkbox" data-bind="checked: isEven(3)" />​

JS

var MyViewModel=function(){ this.isEven = function(num) { return (num % 2) == 0; }; }; ko.applyBindings(new MyViewModel());

-

Una vez dicho esto, es una buena idea tratar de introducir la mayor cantidad posible de lógica en su Modelo de Vista. Sería recomendable crear un modelo de vista que modele su casilla de verificación como un objeto, y luego la lógica sobre si la casilla de verificación debería ser revisada podría ser encapsulada dentro.

-

EDITAR: Basado en el requisito de hacer un enlace bidireccional, he escrito un extensor para administrar un observable.

http://jsfiddle.net/jearles/j6zLW/5/

ko.extenders.bitwise = function(target, bitCount) { target.bits = []; target.checked = ko.observableArray(); // Create bit array based on requested number of bits for (i=bitCount-1; i>=0; i--) { target.bits.push(''''+Math.pow(2, i)); } // Define a function to create bits function makeBits(newValue) { var num = !isNaN(newValue) ? parseInt(newValue) : 0; var arr = []; for (i=0; i<target.bits.length; i++) { var bitValue = parseInt(target.bits[i]); if ((num & bitValue) == bitValue) arr.push(target.bits[i]); } target.checked(arr); } // Define a function to combine bits function makeBitwise(newBits) { var num = 0; for (i=0; i<target.bits.length; i++) { if (newBits.indexOf(target.bits[i]) > -1) num += parseInt(target.bits[i]); } target(num); } // Create initial bits makeBits(target()); // Make bits whenever the value changes target.subscribe(makeBits); // Make number whenever the bits change target.checked.subscribe(makeBitwise); // Return the original observable return target; }; var MyViewModel=function(){ var self = this; this.number = ko.observable(2).extend({ bitwise: 8}); }; ko.applyBindings(new MyViewModel());​


Sin conocer los detalles, parece que lo que deberías hacer es definir un archivo ko.observableArray o un valor de matriz calculado

HTML:

myprop: <input data-bind="value: myprop"> <div data-bind="foreach: selections"> <label> <span data-bind="text: value"></span> <input type="checkbox" data-bind="checked: selected"/> </label> </div>

JS:

$(function() { function Model() { this.self = this self.myprop = ko.observable(14) self.bits = [1, 2, 4, 8, 16, 32, 64, 128] self.selections = ko.computed(function() { return self.bits.map(function(bit) { console.log(myprop() & bit) return { value: bit, selected: (myprop() & bit) == bit } }) }) } ko.applyBindings(new Model()) })

y no pasar valores del marcado para definir el estado del modelo