knockout.js
Fixations
Recherche…
Syntaxe
-
<!-- ko if:myObservable --><!-- /ko -->
-
<i data-bind="if:myObservable"></i>
Remarques
Qu'est-ce qu'une liaison est
Essentiellement, une liaison ou une liaison de données permet de lier vos ViewModels à vos vues (modèles) et inversement. KnockoutJS utilise une liaison de données bidirectionnelle, ce qui signifie que les modifications apportées à votre ViewModel influencent la vue et les modifications apportées à votre vue peuvent influencer le ViewModel.
Sous le capot (bref aperçu)
Les liaisons ne sont que des plugins (scripts) qui vous permettent de résoudre une tâche particulière. Cette tâche modifie le plus souvent le balisage (html) en fonction de votre ViewModel.
Par exemple, une liaison de text
vous permet d'afficher du texte et de le modifier dynamiquement chaque fois que votre ViewModel change.
KnockoutJS est livré avec de nombreuses liaisons puissantes et vous permet de l'étendre avec vos propres liaisons personnalisées.
Et surtout, les liaisons ne sont pas magiques, elles fonctionnent selon un ensemble de règles et chaque fois que vous n'êtes pas sûr de ce que fait une liaison, de ses paramètres ou de sa mise à jour, vous pouvez vous référer au code source de la liaison.
Prenons l'exemple suivant d'une liaison personnalisée:
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 });
}
};
- Une liaison a un nom -
debug
pour que vous puissiez utiliser comme suit:
data-bind="debug: 'foo'"
- La méthode
init
est appelée une fois lorsque la liaison est lancée. Le reste des mises à jour est géré par un calculateur anonyme qui est disposé lorsque l'element
est supprimé. - La liaison s'imprime pour consoler plusieurs choses: la valeur passée dans notre exemple cette valeur est
foo
(cette valeur peut également être observée depuisko.unwrap
méthodeko.unwrap
est utilisée pour la lire), le viewModel actuel et bindingContext. - Chaque fois que la valeur transmise change, la liaison imprime les informations mises à jour sur la console.
- Cette liaison ne peut pas être utilisée avec des éléments virtuels (dans les commentaires html), uniquement sur des éléments réels, car l'indicateur
ko.virtualElements.allowedBindings.debug
n'est pas défini sur true.
Quand utiliser les parenthèses
Sans aucun plugin supplémentaire, KnockoutJS n'aura que des mises à jour de View pour les propriétés du ViewModel qui sont observables ( observable
régulière, mais aussi computed
, pureComputed
, observableArray
, etc.). Une observable serait créée comme ceci:
var vm = { name: ko.observable("John") };
Dans ce cas, vm.name
est une fonction avec deux "modes" distincts:
- Getter:
vm.name()
, sans arguments, obtiendra la valeur actuelle; - Setter:
vm.name("Johnnyboy")
, avec un argument, définira une nouvelle valeur.
Dans les liaisons de données intégrées, vous pouvez toujours utiliser la forme de lecture, et vous pouvez parfois omettre les parenthèses, et la liaison les "ajoutera" effectivement pour vous. Donc, ceux-ci sont équivalents:
<p data-bind="text: name"></p> ... will work
<p data-bind="text: name()"></p> ... works too
Mais cela échouera:
<p data-bind="text: 'Hello, ' + name + '!'"></p> ... FAILS!
Parce que dès que vous voulez "faire" quelque chose avant de passer une valeur à une liaison de données, y compris des comparaisons de valeurs, vous devez "obtenir" correctement les valeurs pour toutes les observables, par exemple:
<p data-bind="text: 'Hello, ' + name() + '!'"></p> ... works
Voir aussi cette Q & R pour plus de détails.
Si / si
Vous pouvez utiliser la liaison if
pour déterminer si les éléments enfants du nœud doivent être créés ou non.
<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>
L'inverse de la liaison if
est ifnot
<div data-bind="ifnot: someProperty">...</div>
est équivalent à
<div data-bind="if: !someProperty()">...</div>
Parfois, vous ne voudrez pas contrôler la présence d'éléments sans avoir à créer un conteneur (généralement pour les éléments <li>
dans les éléments <ul>
ou <option>
intérieur d'un élément <select>
).
Knockout permet cela avec une syntaxe de flux de contrôle sans conteneur basée sur des balises de commentaire comme ceci:
<select>
<option value="0">fixed option</option>
<!-- ko if: featured-->
<option value="1">featured option</option>
<!-- /ko -->
</select>
Pour chaque
Semblable aux répéteurs utilisés dans d'autres langues. Cette liaison vous permettra de répliquer un bloc de HTML pour chaque élément d'un tableau.
<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>
Notez que lorsque nous parcourons notre contexte, il devient l'élément dans le tableau, en l'occurrence une instance de contactViewModel
. Dans un foreach
nous avons également accès à
-
$parent
- le modèle de vue qui a créé cette liaison -
$root
- le modèle de vue racine (peut également être parent) -
$data
- les données à cet index du tableau -
$index
- l'$index
(observable) de base de l'élément rendu
Avec
La liaison with
lie le code HTML dans le noeud lié à un contexte distinct:
<div data-bind="with: subViewModel">
<p data-bind="text: title"></p>
</div>
La liaison with
peut également être utilisée sans élément de conteneur où un élément de conteneur peut ne pas être approprié.
<!-- 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" });
La liaison with
a de nombreuses similitudes avec le template
ou les liaisons foreach
.
Visible
La liaison visible
masquera un élément en appliquant style="display: none;"
à elle lorsque la liaison est évaluée comme 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;
});
}