2012-04-11 9 views
145

Me gustaría utilizar una propiedad en mi ViewModel para alternar qué icono mostrar sin crear una propiedad computada separada de la inversa. es posible?¿Es posible vincular datos visible a la negación ("!") De una propiedad booleana ViewModel?

<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> 

Mi modelo de vista tiene un periodos de propiedad, que es una serie de meses, así:

var month = function() { 
    this.charted = ko.observable(false); 
}; 
+3

@Niko: En realidad no es una pregunta duplicado. El OP de la pregunta a la que se refiere ya sabía ** que ** es posible vincular datos a la negación de un observable, pero se pregunta por qué debe llamarse como una función. El OP de esta pregunta aquí no sabía cómo hacer eso en primer lugar y obviamente no encontró esa otra pregunta. Me alegro de haber encontrado esta pregunta aquí, que es principalmente gracias a su título descriptivo. – Oliver

Respuesta

251

Cuando se utiliza un observable en una expresión que necesita para acceder a ella como una función como:

visible: !charted()

+30

Tal vez deberíamos hacer un enlace oculto :) Tenemos habilitar y deshabilitar. –

+0

¿La documentación no concuerda con esto, o estoy malentendiendo completamente esta página: http://knockoutjs.com/documentation/css-binding.html –

+0

No importa, supongo que "isSevere" no es una propiedad observable, sino una antigua, por lo tanto mi confusión –

48

Estoy de acuerdo con el comentario de John Papa que debería haber incorporado un hidden vinculante. Hay dos ventajas para un enlace dedicado hidden:

  1. Sintaxis más simple, es decir. hidden: charted en lugar de visible: !charted().
  2. Menos recursos, ya que Knockout puede observar el charted observable directamente, en lugar de crear un computed para observar !charted().

Es bastante simple de crear un hidden unión, sin embargo, como esto:

ko.bindingHandlers.hidden = { 
    update: function(element, valueAccessor) { 
    ko.bindingHandlers.visible.update(element, function() { 
     return !ko.utils.unwrapObservable(valueAccessor()); 
    }); 
    } 
}; 

Usted puede usarlo como la incorporada en visible vinculante:

<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> 
+9

esto no funcionó para mí sin retorno 'return! Ko.utils.unwrapObservable (valueAccessor());' –

+0

Gracias @ MehmetAtaş - Corregí el enlace 'oculto' según tu comentario. (Por cierto, estaba usando CoffeeScript en mi proyecto en el momento en que lo publiqué originalmente. La sintaxis de CoffeeScript no lo hace obvio cuando un retorno es intencional.) – Dave

3

usted podría utilizar mi enlace switch/case, que incluye case.visible y 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> 

También podría tener como

 <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> 
+0

Me acabo de dar cuenta de que esta es una vieja pregunta, pero espero que esto pueda ser útil para alguien. –

8

Es poco confuso, ya que tiene que hacer

visible:!showMe() 

Así pues, hice

<span data-bind="visible:showMe">Show</span> 
<span data-bind="visible:!showMe()">Hide</span> 
<label><input type="checkbox" data-bind="checked:showMe"/>toggle</label>​ 

mi modelo es

var myModel={ 
    showMe:ko.observable(true) 
} 
ko.applyBindings(myModel);  

cheque en violín http://jsfiddle.net/khanSharp/bgdbm/

1

Con el fin de dar a conocer la unión de los cambios en la propiedad, que copió el manejador de unión visible y se invierte:

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 = ""; 
    } 
}; 
0

responsabilidad: esta solución es solo para fines de entretenimiento.

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 
--> 
-1

También puede utilizar oculta así:

<div data-bind="hidden: isString"> 
          <input type="text" class="form-control" data-bind="value: settingValue" /> 
         </div> 
Cuestiones relacionadas