Нокаут проверил обязательную проблему - PullRequest
1 голос
/ 17 февраля 2012

У меня проблема с привязками флажков, которые не работают с KnockoutJS 2.0. У меня есть массив объектов. Одним из свойств этих объектов является массив различных объектов. В дочерних объектах есть несколько свойств, одним из которых является логическое значение. Я строю список для каждого родительского объекта, и под каждым родителем я показываю своих детей. Для каждого списка детей у меня есть два представления: только чтение и редактирование. В только для чтения у меня есть изображения, которые представляют, проверяется ли элемент на основе логического свойства. Это работает, и если я обновляю логическое значение через консоль, я вижу то, что ожидал - изображение исчезает или отображается в зависимости от назначенного мной значения. В режиме редактирования изображения заменяются флажком. Такое же поведение наблюдается при обновлении значения через консоль - оно проверяется, когда ожидаю, а не когда нет. Проблема возникает, когда я устанавливаю или снимаю флажок. Это не меняет базовое значение, к которому привязан флажок.

Вот основная идея моих данных.

[
    {
        "xxx": "yyy",
        "xxx": "yyy",
        ...
        "Displays": [
            {
            "xxx": "yyy",
            ...
                "Excluded": false,
            },
            {
            "xxx": "yyy",
             ...
                "Excluded": true,
            }
        ],
    }
]

Вот привязка

<input type="checkbox" data-bind="checked: !Excluded()" />

Ответы [ 3 ]

3 голосов
/ 18 февраля 2012

проблема в том, что «флажок» здесь является двунаправленной привязкой: свойство привязки должно быть прочитано для создания правильного представления, но также должно быть обновлено, когда вы нажимаете на флажок. Сравните это с привязкой вроде:

<span data-bind="text: 'your name is ' + name()"></span>

когда выражение только для чтения, поэтому вы можете использовать выражение (и вам нужно развернуть наблюдаемое).

Итак, вам нужно привязать непосредственно к наблюдаемому свойству, не «разворачивая» его, добавив «()», это будет выполнено нокаутом при необходимости, как для чтения, так и для записи:

<input type="checkbox" data-bind="checked: Excluded" />

См. http://jsfiddle.net/saurus/usKwA/ для простого примера. Обратите внимание, как метки флажков обновляются при изменении, показывая, что модель обновлена ​​и рендеринг запускается правильно.

Если вам нужно отрицать значение (чтобы флажок был установлен, когда значение равно false), вы можете добавить вычисляемую наблюдаемую запись с возможностью записи, как описано в http://knockoutjs.com/documentation/computedObservables.html разделе «Доступные для записи вычисляемые наблюдаемые», или может отрицать данные в viewmodel, делая это на сервере непосредственно перед отправкой данных или на клиенте перед заполнением viewmodel.

надеюсь, это поможет.

2 голосов
/ 15 июня 2012

Я знаю, что мой ответ немного запаздывает с этой игрой, но у меня была эта проблема сегодня, и это был самый близкий поток, который я мог найти, связанный с этой проблемой, и, похоже, нет ответа, который решает ее.Итак, вот мое решение.

По сути, проблема в том, что нокаут действительно хочет, чтобы ваши значения viewModel были строковыми, а не логическими, но это не всегда практично.Итак, я создал привязку под названием isChecked, которая работает строго с логическими значениями. Примечание : Это будет работать только с наблюдаемыми свойствами.

ko.bindingHandlers.isChecked = {
    getElementDeclaredValue: function (element) {
        var declaredValue = element.getAttribute("value");

        // If a value is provided, we presume it represents "true",
        // unless its explicitly "false". If no value is provided, we
        // presume that a checked state would equal "true".
        return declaredValue && Boolean.isBool(declaredValue)
            ? Boolean.parse(declaredValue)
            : true;
    },

    init: function (element, valueAccessor) {
        var updateHandler = function () {
            var declaredValue = ko.bindingHandlers.isChecked.getElementDeclaredValue(element);
            var elementValue = element.checked ? declaredValue : !declaredValue;

            var modelValue = valueAccessor();
            var currentValue = ko.utils.unwrapObservable(modelValue);

            if (elementValue === currentValue)
                return;

            if (ko.isObservable(modelValue)) {
                modelValue(elementValue);
            }
        };

        ko.utils.registerEventHandler(element, "click", updateHandler);
    },

    update: function (element, valueAccessor) {
        var elementValue = ko.bindingHandlers.isChecked.getElementDeclaredValue(element);
        element.checked = elementValue === ko.utils.unwrapObservable(valueAccessor());
    }
};

Два логических метода ("parse" и "isBool") определены следующим образом:

Boolean.isBool = function (value) {
    return (/^(?:true|false)$/i).test(value);
};

Boolean.parse = function (value) {
    return (/^true$/i).test(value);
};

Я проигнорирую любые комментарии, которые говорят, что я не должен изменять встроенный прототип объекта;Я сделаю так, как мне хорошо, пожалуйста; -).

Использование такое же, как проверенное связывание.Атрибут «value» является необязательным, если только вы не хотите, чтобы проверенное состояние представляло ложное:

<input type="radio" id="rbNewClaim" name="ClaimType" value="false" data-bind="checked: isExistingClaim" />

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 21 февраля 2012

Я прекратил попытки заставить это работать со значениями bool и создал массив выбранных объектов и обработал его таким образом.Это не оптимальное решение, но я устал бороться с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...