Knockoutjs css binding no funciona

(Usando KnockoutJs 2.0.0)

Tengo una list de numbers de teléfono en mi model de vista. Cada número de teléfono tiene un tipo (casa, trabajo, mobile, etc.). Quiero mostrar un icono (basado en una class fontawesome) al lado de cada número de teléfono.

Si codigo los íconos en el enlace css, todo funciona:

<tbody data-binding="foreach: phoneList"> <tr> <td><span data-bind="css: {'icon-home' : TypeId() == 1, 'icon-building': TypeId() == 2, ... , 'icon-phone': TypeId() >= 7></span></td> ... </tbody> 

Quería replace la list codificada con una llamada a una function. Inicialmente traté de agregar la function al padre pero no tuve éxito, así que intenté agregar la function directamente al object del teléfono como function y como ko.computed() , pero ninguno de estos me funciona.

He inventado aquí un código que demuestra el problema. Si inspecciona el elemento de tramo de los elementos de la tabla, verá que casi parece que los destinatarios de datos tratan la cadena devuelta como una matriz de caracteres y configuran la class según los índices en lugar de tratar la cadena devuelta como una class.

Estoy seguro de que esto es algo completamente obvio, pero me he estado golpeando la cabeza en vano.

Un observable calculado debería funcionar bien. El problema es qué es lo que estás volviendo de ese observable calculado. Debe devolver la definición de classs en el mismo formatting que la versión codificada:

 me.getClass = ko.computed(function() { return me.typeId() == 1 ? { 'mobile': true } : { 'business': true }; }); 

Vea la versión actualizada aquí: http://plnkr.co/edit/qDjgMlZpXHjn5ixY3OCt

O bien, podría definir un enlace personalizado para limpiar un poco la function calculada, aunque debe tenerse en count que en este caso todas las classs serán reemplazadas por el resultado de la vinculación. Esto probablemente no es necesario en Knockout 3.0.0, como se alude en los comentarios y otras respuestas.

Unión:

 ko.bindingHandlers.setClass = { update: function(element, valueAccessor, allBindings) { var value = ko.utils.unwrapObservable(valueAccessor()); element.className = value; } }; 

Observable:

 me.setClass = ko.computed(function() { return me.typeId() == 1 ? "mobile" : "business"; }); 

HTML:

 <td data-bind="setClass: setClass, text: typeId"></td> 

Una versión que usa un enlace personalizado está aquí: http://plnkr.co/edit/ryaA4mIf7oh5Biu8bKj0?p=info

Fijar

Ejemplo

Actualicé tu versión de KO a 3.0.

Luego, cambié tu enlace ko.computed por getClass de:

me.getClass = ko.computed(function() { return me.typeId == 1 ? "mobile" : "business"; });

a:

me.getClass = ko.computed(function() { return this.typeId() == 1 ? "mobile" : "business"; }, me);

Nota

Puede haber una manera de hacer esto con KO 2.0, pero no pude encontrar la documentation de versiones anteriores. Imagino que el problema está relacionado con la syntax si la característica existe.

Una forma alternativa de hacerlo es utilizar un data binding attr, en lugar de utilizar un controller de enlace personalizado para establecer la class en el elemento.

Por lo tanto, aún necesitaría usar un cálculo para establecer lo observable:

 me.setClass = ko.computed(function() { return me.typeId() === 1 ? "mobile" : "business"; }); 

A continuación, utilice un enlace attr para establecer la class en el elemento html:

 <td data-bind="attr: { class: setClass }, text: typeId"></td>