Knockout将多个checkedValue绑定到输入

时间:2017-11-15 12:23:13

标签: javascript jquery knockout.js radio-button

我有自定义下拉列表(使用div和列表制作)

<div class="primary-tags-wrapper">
    <div id="primaryTag" class="primary-tags-dropdown ui-dropdown fl">
        <div class="fl">
            <div class="primary-tag-selected-value" data-bind="text: showPrimaryTag"></div>
        </div>
        <div class="fr" data-primary="tag">
            <div class="fa fa-caret-down"></div>
            <ul class="primary-tags-list">
                <li class="primary-tags-item">
                    <input class="primary-tags-item-radio" type="radio" name="primary-tag" id="primary-tag-default" data-bind="checkedValue: null, checked: primaryTag"/>
                    <label class="primary-tags-item-label" for="primary-tag-default">Set Primary Tag</label>
                </li>
                <!-- ko foreach: tags -->
                <li class="primary-tags-item">
                    <input class="primary-tags-item-radio" type="radio" name="primary-tag" data-bind="attr: { 'id': 'primary-tag-' + $index() }, checkedValue: $data, checked: $parent.primaryTag"/>
                    <label class="primary-tags-item-label" data-bind="attr: { 'for': 'primary-tag-' + $index() }, text: $data"></label>
                </li>
                <!-- /ko -->
                <li class="primary-tags-item">
                    <input type="button" class="btn green-btn" data-bind="click: savePrimaryTag" value="Save"/>
                </li>
            </ul>
        </div>
    </div>
</div>

对此我已经绑定了淘汰赛ViewModel

var TagsViewModel = function (inputModel) {
            var vm = this;

            vm.tags = ko.observableArray(inputModel.tags);
            vm.allTags = ko.observableArray(inputModel.allTags);
            vm.primaryTag = ko.observable(inputModel.primaryTag);

            vm.refreshTags = function () {
                var data = vm.tags().slice(0);
                vm.tags([]);
                vm.tags(data);
            };

            vm.savePrimaryTag = function() {
                var data = {
                    locationId: inputModel.locationId,
                    reviewId: inputModel.reviewId,
                    tag: vm.primaryTag()
                };

                initializeAjaxLoader();

                $.post('/data/reviews/primaryTag',
                    data,
                    function(response) {
                        if (!response.status) {
                            vm.primaryTag('');
                        } else {
                            vm.primaryTag(response.tag);
                        }

                        removeAjaxLoader();
                    });
            }

            vm.showPrimaryTag = ko.pureComputed(function() {
                    var primaryTagVal = vm.primaryTag();
                    if (primaryTagVal) {
                        return 'Primary Tag: ' + primaryTagVal;
                    }
                    return DEFAULT_PRIMARY_TAG;
                },
                vm);

            vm.noPrimaryTagSelected = ko.pureComputed(function() {
                    var primaryTagVal = vm.primaryTag();
                    if (primaryTagVal) {
                        return false;
                    }
                    return true;
                },
                vm);
        }

在下拉列表中,我有默认选项:“设置主标记”,应在primaryTagnullstring.Empty时选择。目前,这是我无法实现的目标。

因此可以将多个checkedValue设置为radio按钮,或者有另一种方法来支持此“功能”

1 个答案:

答案 0 :(得分:0)

当knockout处理checked绑定时,它使用===比较基元。这意味着,正如您所注意到的,null的选中值不适用于""falseundefined0

如果您以某种方式无法阻止将所选值初始化为空字符串,则可以绑定到“清理”输出的computed图层。

  • 所有无线电输入都将其值写入计算的可观察量。
  • 计算出的observable有一个私有支持字段来存储原始输入
  • read方法可确保将所有falsey值返回为null

var VM = function() {
  // Notice this can be initialized as any falsey value
  // and the checkedValue=null binding will work.
  const _selectedTag = ko.observable("");
  
  this.selectedTag = ko.computed({
    read: function() {
      // Explicitly "cast" all falsey values
      // to `null` so it can be handled by
      // knockout's `checked` binding:
      return _selectedTag() || null;
    },
    write: _selectedTag
  });
  
  this.tags = [
    { label: "one" },
    { label: "two" },
    { label: "three" },
    { label: "four" },
  ]
};

ko.applyBindings(new VM());
label { display: block }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div>
  <label>
    <input type="radio" data-bind="checked: selectedTag, checkedValue: null">
    Don't use a tag
  </label>

  <!-- ko foreach: tags -->
    <label>
      <input type="radio" data-bind="checked: $parent.selectedTag, checkedValue: $data">
      <span data-bind="text: label"></span>
    </label>
  <!-- /ko -->

</div>