knockout.js
Fijaciones
Buscar..
Sintaxis
-
<!-- ko if:myObservable --><!-- /ko -->
-
<i data-bind="if:myObservable"></i>
Observaciones
Lo que es un enlace
Esencialmente, un enlace o un enlace de datos es una forma de vincular sus ViewModels a sus Vistas (plantillas) y viceversa. KnockoutJS utiliza enlace de datos bidireccional, lo que significa que los cambios en su ViewModel influyen en la Vista y los cambios en su Vista pueden influir en el ViewModel.
Bajo el capó (breve descripción)
Los enlaces son solo complementos (scripts) que le permiten resolver una tarea en particular. Esta tarea es más a menudo que no es cambiar el marcado (html) de acuerdo con su ViewModel.
Por ejemplo, un enlace de text
permite mostrar texto y cambiarlo dinámicamente cada vez que cambie su ViewModel.
KnockoutJS viene con muchos enlaces poderosos y le permite extenderlo con sus propios enlaces personalizados.
Y lo más importante es que los enlaces no son mágicos, funcionan de acuerdo con un conjunto de reglas y, en cualquier momento que no esté seguro de qué hace el enlace, qué parámetros toma o cuándo actualizará la vista, puede consultar el código fuente del enlace.
Considere el siguiente ejemplo de un enlace personalizado:
ko.bindingHandlers.debug = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.computed(function () {
var value = ko.unwrap(valueAccessor());
console.log({
value: value,
viewModel: viewModel,
bindingContext: bindingContext
});
}, null, { disposeWhenNodeIsRemoved: element });
}
};
- Un enlace tiene un nombre:
debug
por lo que puede usar lo siguiente:
data-bind="debug: 'foo'"
- El método
init
se llama una vez cuando se inicia el enlace. El resto de las actualizaciones se manejan mediante un cálculo anónimo que se elimina cuando se elimina elelement
. - El enlace imprime en la consola varias cosas: el valor pasado en nuestro ejemplo, este valor es
foo
(este valor también puede observarse ya que el métodoko.unwrap
se usa para leerlo), el viewModel actual y bindingContext. - Siempre que el valor pasado cambie, el enlace imprimirá la información actualizada en la consola.
- Este enlace no se puede usar con elementos virtuales (en comentarios html), solo en elementos reales, ya que el indicador
ko.virtualElements.allowedBindings.debug
no está establecido en verdadero.
Cuándo usar paréntesis
Sin ningún complemento adicional, KnockoutJS solo tendrá actualizaciones de Vista en vivo para las propiedades en ViewModel que sean observables ( observable
regulares, pero también computed
, pureComputed
, observableArray
, etc.). Un observable se crearía así:
var vm = { name: ko.observable("John") };
En este caso, vm.name
es una función con dos "modos" separados:
- Getter:
vm.name()
, sin argumentos, obtendrá el valor actual; - Setter:
vm.name("Johnnyboy")
, con un argumento, establecerá un nuevo valor.
En los enlaces de datos integrados, siempre puede utilizar el formulario de obtención, y en ocasiones puede omitir los paréntesis, y el enlace los "agregará" de manera efectiva. Así que estos son equivalentes:
<p data-bind="text: name"></p> ... will work
<p data-bind="text: name()"></p> ... works too
Pero esto fallará:
<p data-bind="text: 'Hello, ' + name + '!'"></p> ... FAILS!
Porque tan pronto como quiera "hacer" algo antes de pasar un valor a un enlace de datos, incluidas las comparaciones de valores, debe "obtener" correctamente los valores de todos los observables, por ejemplo:
<p data-bind="text: 'Hello, ' + name() + '!'"></p> ... works
Vea también este Q&A para más detalles.
Si / si no
Puede usar el enlace if
para determinar si se deben crear o no los elementos secundarios del nodo.
<div class="product-info">
<h2> Product1 </h2>
<img src="../products/product1.jpg"/>
<span data-bind="if:featured">
<span class="featured"></span>
</span>
<span data-bind="ifnot:inStock">
<span class="out-of-stock"></span>
</span>
</div>
<script>
ko.applyBindings({
product: {
featured: ko.observable(true),
inStock: ko.observable(false)
}
});
</script>
El inverso de la unión if
es ifnot
<div data-bind="ifnot: someProperty">...</div>
es equivalente a
<div data-bind="if: !someProperty()">...</div>
A veces, no podrá controlar la presencia de elementos sin tener que crear un contenedor (normalmente para los elementos <li>
en un elemento <ul>
o <option>
dentro de un <select>
)
Knockout habilita esto con una sintaxis de flujo de control sin contenedor basada en etiquetas de comentarios como las siguientes:
<select>
<option value="0">fixed option</option>
<!-- ko if: featured-->
<option value="1">featured option</option>
<!-- /ko -->
</select>
Para cada
Similar a los repetidores utilizados en otros idiomas. Este enlace le permitirá replicar un bloque de html para cada elemento en una matriz.
<div data-bind="foreach:contacts">
<div class="contact">
<h2 data-bind="text:name">
<p data-bind="text:info">
</div>
</div>
<script type="text/javascript">
var contactViewModel = function (data) {
this.name = ko.observable(data.name);
this.info = ko.observable(data.info);
};
ko.applyBindings({
contacts: [
new contactViewModel({name:'Erik', info:'[email protected]'}),
new contactViewModel({name:'Audrey', info:'[email protected]'})
]
});
</script>
Tenga en cuenta que cuando hacemos un bucle a través de nuestro contexto se convierte en el elemento dentro de la matriz, en este caso una instancia de contactViewModel
. Dentro de un foreach
también tenemos acceso a
-
$parent
: el modelo de vista que creó este enlace -
$root
: el modelo de vista raíz (también podría ser padre) -
$data
- los datos en este índice de la matriz -
$index
- el índice basado en cero (observable) del elemento renderizado
Con
El enlace with
vincula el HTML dentro del nodo enlazado a un contexto separado:
<div data-bind="with: subViewModel">
<p data-bind="text: title"></p>
</div>
El enlace with
también se puede usar sin un elemento contenedor, donde un elemento contenedor puede no ser apropiado.
<!-- ko with: subViewModel -->
<p data-bind="text: title"></p>
<!-- /ko -->
var vm = {
subViewModel: ko.observable()
};
// Doesn't throw an error on the `text: title`; the `<p>` element
// isn't bound to any context (and even removed from the DOM)
ko.applyBindings(vm);
// Includes the `<p>` element and binds it to our new object
vm.subViewModel({ title: "SubViewModel" });
El enlace with
tiene muchas similitudes con la template
o foreach
enlaces.
Visible
El enlace visible
ocultará un elemento aplicando style="display: none;"
A ella cuando el enlace se evalúe como falsey.
<input type="text" data-bind="textInput: name"> <span class="error" data-bind="visible: isInvalid">Required!</span>
ko.applyBindings(new ViewModel());
function ViewModel(){
var vm = this;
vm.name = ko.observable("test");
vm.isInvalid = ko.computed(function() {
return vm.name().length == 0;
});
}