Работа со списком флажков в knockoutjs

Я пытаюсь окунуться в Knockout.js, и я просто застрял, когда дело доходит до флажков.

Серверная часть Я заполняю набор флажков с их соответствующими значениями. Теперь, когда отмечен какой-либо из отмеченных флажков, мне нужно сохранить это значение в строке, разделенной запятыми. Когда они не отмечены, значение нужно удалить из строки.

У кого-нибудь есть намек на то, как добиться этого с помощью нокаутов?

У меня есть следующий код:

ViewModel:

$().ready(function() {
   function classPreValue(preValue)
   {
       return {
            preValue : ko.observable(preValue)
       } 
   }

   var editOfferViewModel = {
   maxNumOfVisitors : ko.observable(""),
   goals : ko.observable(""),
   description : ko.observable(""),
   contact : ko.observable(""),
   comments : ko.observable(""),
   classPreValues : ko.observableArray([]),
   addPreValue : function(element) {
      alert($(element).val());
      this.classPreValues.push(new classPreValue(element.val()));
   }
 };

 ko.applyBindings(editOfferViewModel);
});

И мои флажки заполняются циклом foreach:

<input data-bind="checked: function() { editOfferViewModel.addPreValue(this) }"
       type="checkbox" checked="yes" value='@s'>
    @s
</input>

Я пытаюсь передать элемент флажка в качестве параметра моей функции addPreValue(), но ничего не происходит, когда я устанавливаю флажок?

Любая помощь/подсказки по этому поводу приветствуются!

Ответ 1

Проверенное связывание ожидает передачи структуры, которую она может читать/писать. Это может быть переменная, наблюдаемая или доступная для записи зависимая функция.

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

Вот пример, который также включает вычисляемый наблюдаемый, который содержит массив как значения, разделенные запятой. http://jsfiddle.net/rniemeyer/Jm2Mh/

var viewModel = {
    choices: ["one", "two", "three", "four", "five"],
    selectedChoices: ko.observableArray(["two", "four"])
};

viewModel.selectedChoicesDelimited = ko.computed(function() {
    return this.selectedChoices().join(",");
}, viewModel);

ko.applyBindings(viewModel);

HTML:

<ul data-bind="template: { name: 'choiceTmpl', foreach: choices, templateOptions: { selections: selectedChoices } }"></ul>

<script id="choiceTmpl" type="text/html">
    <li>
        <input type="checkbox" data-bind="attr: { value: $data }, checked: $item.selections" />
        <span data-bind="text: $data"></span>
    </li>
</script>

Ответ 2

Почему здесь нет взаимозависимых флажков? Где-то где-то

Поскольку эта ссылка возникла первой, в то время как я искал взаимоисключающие флажки, я поделюсь своим ответом здесь. Я все время пытался ударить головой о стену. Кстати, когда вы обрабатываете событие click в привязке in-line knockoutjs, оно, похоже, отключает привязки (возможно, только потому, что я попытался вызвать функцию resetIllnesses, как определено ниже), даже если вы вернете true из функции. Может быть, есть лучший способ, но до тех пор следуйте моему примеру.

Вот тип, который мне нужно связать.

var IllnessType = function (name,title) {
    this.Title = ko.observable(title);
    this.Name = ko.observable(name);
    this.IsSelected = ko.observable(false);
};

Массив для привязки.

model.IllnessTypes = ko.observableArray(
    [new IllnessType('IsSkinDisorder', 'Skin Disorder'),
        new IllnessType('IsRespiratoryProblem', 'Respiratory Problem'),
        new IllnessType('IsPoisoning', 'Poisoning'),
        new IllnessType('IsHearingLoss', 'Hearing Loss'),
        new IllnessType('IsOtherIllness', 'All Other Illness')]
);

Функция болезни reset, чтобы очистить их все.

model.resetIllnesses = function () {
    ko.utils.arrayForEach(model.IllnessTypes(), function (type) {
        type.IsSelected(false);
    });
};

Разметка

<ul data-bind="foreach:IllnessTypes,visible: model.IsIllness()">
    <li><label data-bind="html: Title"></label></li>
    <li><input class="checkgroup2" type="checkbox" 
data-bind="attr:{name: Name },checked:IsSelected" /></li>
</ul>

Это просто не работает

Если вы боретесь с попыткой вызвать функцию resetIllness, как я ниже, вы почувствуете мою боль.

<input type='checkbox' data-bind="checked:IsSelected, 
  click: function() { model.resetIllnesses(); return true; }" />

вы делились моей болью. Ну, это работает! когда вы вызываете его из следующего примера. Обратите внимание, что есть класс, который я добавил выше, чтобы добавить функцию click.

script, который устраняет все ваши проблемы.

<script type="text/javascript">
    $(function() {
        $(".checkgroup2").on('click', function() {
            model.resetIllnesses();
            var data = ko.dataFor(this);
            data.IsSelected(true);
        });
    });
</script>

Отправить информацию на сервер

Кроме того, в моем случае мне пришлось отправлять информацию на сервер по-другому, чем формат html по умолчанию, поэтому я немного изменил входные данные.

<input class="checkgroup2" type="checkbox" data-bind="checked:IsSelected" />
<input type="hidden" data-bind="attr:{name: Name },value:IsSelected" />