Pregunta

El ver código:

<ul data-bind="foreach: BackColorOptions">
    <li data-bind="css: { selected: Selected }">
        <label>
            <input type="radio" name="BackColorOption" 
                data-bind="value: Color, checked: $root.BackColor" />
        </label>
    </li>
</ul>
@{
    var jsonModel = new System.Web.Script.Serialization.
        JavaScriptSerializer().Serialize(Model);
}
<input type="hidden" id="JsonModel" value='@jsonModel' />

El viewmodel código:

var initialData = $.parseJSON($('#JsonModel').val());

function BackColorOption(data, parent) {
    var self = this;
    self.parent = parent;
    self.Text = ko.observable(data.Text);
    self.Color = ko.computed(function () {
        return '#' + self.Text().toLowerCase();
    });
    self.Selected = ko.computed(function () {
        var backColor = self.parent.BackColor();
        if (backColor) {
            return backColor.toLowerCase() == self.Color;
        }
        return false;
    });
}

function TestViewModel() {
    var self = this;

    self.BackColor = ko.observable(initialData.BackColor);

    var mappedBackColorOptions = $.map(initialData.BackColorOptions, 
        function (item) {
            return new BackColorOption(item, self);
        }
    );
    self.BackColorOptions = ko.observableArray(mappedBackColorOptions);

}

ko.applyBindings(new TestViewModel());

El modelo código:

string BackColor { get; set; }
SelectListItem[] BackColorOptions
{
    get
    {
        return new[] 
        { 
            new SelectListItem{Text = "cc0000"},
            new SelectListItem{Text = "ff9900"},
            new SelectListItem{Text = "dddd33"},
            new SelectListItem{Text = "009900"},
            new SelectListItem{Text = "00cccc"},
            new SelectListItem{Text = "0066ff"},
            new SelectListItem{Text = "9900ff"},
            new SelectListItem{Text = "ff00ff"},
        };
    }
}

El código anterior funciona como se esperaba en IE (8) y Chrome (17), pero no FF (10.0.2).Estoy básicamente tratando de hacer un selector de color similar a la de GitHub problema de las etiquetas.La vista muestra un conjunto de botones de radio, puede hacer clic en para seleccionar un color.Cuando la radio está activada, puedo añadir un selected css class a los padres <li>.La clase css provoca un icono de marca de verificación que aparecen en la <li>.

En Firefox, la clase css sólo se aplica después de que un usuario ha ido pasando y comprueba que el botón de radio al menos una vez.Yo depurar y encontraron que esto es debido a la forma en la self.Color calcula observables se evalúa en el BackColorOption el cierre.Antes de la primera vez que la radio está activada, typeof(self.Color) == 'function' evalúa a true.Sin embargo, después de que está activada, typeof(self.Color) == 'string' evalúa a true.

Este typeof(self.Color) el comportamiento es el mismo de acuerdo tanto con Firefox y Chrome js depurador.Sin embargo, el problema en FF es porque de esta línea en el self.Selected calcula observable en la BackColorOption cierre:

return backColor.toLowerCase() == self.Color;

Chrome & IE todavía devolver cierto incluso cuando self.Color es una función en lugar de una cadena.Sin embargo Firefox no.Cuando self.Color es una función, devuelve false.Esta es la razón por la que usted tiene que comprobar cada radio al menos una vez antes de la clase css se agrega a la <li> y aparece el icono.

Todavía soy un poco nuevo en octavos de final, y no puede ser adecuadamente llamar a un viewmodel de la propiedad como una función cuando se supone que debería.Todavía estoy un poco confuso cuando el uso de la () el paréntesis y cuando a omitirlos.Hay otra forma de escribir el self.Selected calcula observable, que depende de la self.Color calcula observable (en el BackColorOption de cierre)?

Actualización 1

Yo era capaz de conseguir que esto funcione en FF 10.0.2 con lo siguiente:

self.Selected = ko.computed(function () {
    var backColor = self.parent.BackColor();
    var selfColor = self.Color;
    if (typeof (selfColor) === 'function')
        selfColor = self.Color();
    if (backColor) {
        return backColor.toLowerCase() === selfColor;
    }
    return false;
});

Sin embargo, esto se siente como que estoy luchando por nocaut.¿No se supone que "sólo el trabajo"?

¿Fue útil?

Solución

El value unión en KO no es realmente ideal para los botones de radio y casillas de verificación.En su situación, usted necesita sus botones de radio para tener un value atributo de modo que cuando se haga clic en ellos, ese valor se puede utilizar para actualizar su TestViewModel.BackColor observable.

Normalmente con los botones de la radio, usted no desea que el value atributo para cambiar (si alguna vez) una vez que el html se representa.

Así que, he cambiado la plantilla html del uso de un value la unión a en lugar de utilizar un attr unión (atributo html).Este es ahora sólo de la configuración de la value atributo html de su botones de radio.El checked vinculante, a continuación, mantiene su TestViewModel.BackColor observable sincronizado con lo que el value es el botón de radio que se comprueba.

Ver este violín:http://jsfiddle.net/m2KQ2/

También, la línea en su BackColorOption la función tiene una errata:

self.Selected = ko.computed(function () {
    var backColor = self.parent.BackColor();
    if (backColor) {
        return backColor.toLowerCase() == self.Color; //<-- should be Color();
    }
    return false;
});
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top