J'aimerais utiliser une propriété sur mon ViewModel pour changer l'icône à afficher sans créer une propriété calculée séparée de l'inverse. Est-ce possible?
<tbody data-bind="foreach: periods">
<tr>
<td>
<i class="icon-search" data-bind="visible: !charted, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="visible: charted, click: $parent.pie_it"></i>
</td>
</tr>
</tbody>
Mon ViewModel a une propriété périodes qui est un tableau de mois, comme ceci:
var month = function() {
this.charted = ko.observable(false);
};
Lorsque vous utilisez un observable dans une expression, vous devez y accéder en tant que fonction telle que:
visible: !charted()
Je suis d'accord avec le commentaire de John Papa selon lequel il devrait exister une liaison hidden
intégrée. Une liaison hidden
dédiée présente deux avantages:
hidden: charted
au lieu de visible: !charted()
.charted
plutôt que de créer un computed
pour observer !charted()
.C'est assez simple pour créer une liaison hidden
, cependant, comme ceci:
ko.bindingHandlers.hidden = {
update: function(element, valueAccessor) {
ko.bindingHandlers.visible.update(element, function() {
return !ko.utils.unwrapObservable(valueAccessor());
});
}
};
Vous pouvez l'utiliser comme la liaison visible
intégrée:
<i class="icon-search" data-bind="hidden: charted, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="visible: charted, click: $parent.pie_it"></i>
C'est peu déroutant, comme vous devez le faire
visible:!showMe()
alors je l'ai fait
<span data-bind="visible:showMe">Show</span>
<span data-bind="visible:!showMe()">Hide</span>
<label><input type="checkbox" data-bind="checked:showMe"/>toggle</label>
mon modèle est
var myModel={
showMe:ko.observable(true)
}
ko.applyBindings(myModel);
Check in fiddle http://jsfiddle.net/khanSharp/bgdbm/
Vous pouvez utiliser ma liaison switch/case , qui inclut case.visible
et casenot.visible
.
<tbody data-bind="foreach: periods">
<tr>
<td data-bind="switch: true">
<i class="icon-search" data-bind="case.visible: $else, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="case.visible: charted, click: $parent.pie_it"></i>
</td>
</tr>
</tbody>
Vous pourriez aussi l'avoir comme
<i class="icon-search" data-bind="casenot.visible: charted, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="case.visible: $else, click: $parent.pie_it"></i>
Afin de rendre la liaison consciente des modifications apportées à la propriété, j'ai copié le gestionnaire de liaison visible et l'inversé:
ko.bindingHandlers.hidden = {
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var isCurrentlyHidden = !(element.style.display == "");
if (value && !isCurrentlyHidden)
element.style.display = "none";
else if ((!value) && isCurrentlyHidden)
element.style.display = "";
}
};
Avertissement: cette solution est uniquement à des fins de divertissement.
ko.extenders.not = function (target) {
target.not = ko.computed(function () {
return !target();
});
};
self.foo = ko.observable(true).extend({ not: null });
<div data-bind="text: foo"></div> <!-- true -->
<div data-bind="text: foo.not"></div> <!-- false -->
<!-- unfortunately I can't think of a way to be able to use:
text: foo...not
-->
J'avais le même problème sur la façon d'utiliser un opposé à un observable booléen. J'ai trouvé une solution facile:
var ViewModel = function () {
var self = this;
// When program start, this is set to FALSE
self.isSearchContentValid = ko.observable(false);
self.gatherPlacesData = function () {
// When user click a button, the value become TRUE
self.isSearchContentValid(true);
};
Maintenant, sur votre HTML, vous devriez le faire
<p data-bind = "visible:isSearchContentValid() === false"> Text 1</p>
<p data-bind = "visible:isSearchContentValid"> Text 2</p>
Lorsque le programme démarre, seul "Text1" est visible car "false === false est TRUE" et Text2 n'est pas visible.
Disons que nous avons un bouton qui appelle l'événement de rassemblementPlacesData sur click. Désormais, Text1 ne sera pas visible car "true === false est FALSE" et Text 2 uniquement.
Une autre solution possible pourrait être d'utiliser l'observable calculé, mais je pense que c'est une solution trop compliquée pour un problème aussi simple.