【问题标题】:Knockoutjs:Select data binding behaviourKnockoutjs:选择数据绑定行为
【发布时间】:2019-09-13 05:52:15
【问题描述】:

如果选择美国作为国家,则从国家下拉列表中,它应该将州显示为下拉列表,否则它应该是一个简单的输入文本框。

我们有下面的国家选择下拉列表,其中包含一个数组作为选项:

<select class="form-control" name="sCountry" aria-required="true"
        data-bind="enable: $parents[1].shippingCountriesPriceListGroup().length, options: $parents[1].shippingCountriesPriceListGroup, optionsText: 'displayName',
                             optionsValue: 'countryCode', optionsCaption: $parents[1].resources().countryText, value: selectedCountry,
</select>

如果选择的国家是美国,我已经使用了敲除 ififnot 绑定来实现显示状态下拉列表的上述条件。

敲除数据绑定:

<!-- ko if:selectedCountry()=="US" -->
   <div class="form-group col-md-6 col-sm-12">
      <label class="control-label"
                       data-bind="widgetLocaleText:'stateText', attr: {for: $addrPrefix + 'CC-checkoutAddressBook-sstate'}"></label>
<select class="col-md-12 form-control" name="sState" id="CC-checkoutAddressBook-sstate" aria-required="true"
                    data-bind="options: $parents[1].US_stateList, optionsText: 'displayName', optionsValue: 'abbreviation',optionsCaption:'Choose State..',
                    value: tms_state,attr: {id: $addrPrefix + 'CC-checkoutAddressBook-sstate'}">
                </select>
            </div>
            <!-- /ko -->
<!-- ko ifnot:selectedCountry()=="US" -->
            <div class="form-group col-md-6 col-sm-12">
                <label class="control-label"
                       data-bind="widgetLocaleText:'stateText', attr: {for: $addrPrefix + 'CC-checkoutAddressBook-sstate'}"></label>
                <input class="col-md-12 form-control" name="sState"
                       aria-required="true"
                       data-bind="value: tms_state, attr: {id: $addrPrefix + 'CC-checkoutAddressBook-sstate'}">
            </div>
 <!-- /ko -->

Javascript 代码:

US_stateList 数组:

US_stateList:ko.observableArray([{displayName:"Armed Forces Americas",abbreviation:"AA"},{displayName:"Armed Forces Europe",abbreviation:"AE"},{displayName:"Alabama",abbreviation:"AL"},{displayName:"Alaska",abbreviation:"AK"}])

我已订阅 selectedCountry 可观察值,以便在选择非美国州时将状态框值设置为 null 或空。

widget.newShippingAddress().selectedCountry.subscribe(function(newValue){
                    if ((widget.newShippingAddress().tms_state() !== undefined) ||
                    (widget.newShippingAddress().tms_state() !== '')) {
                    // needs to be null rather than empty string
                    // or knockout resets to dropdown value

                        widget.newShippingAddress().tms_state(null);
                }
                });

如果所选国家/地区是美国,则预期结果是将 state 字段显示为下拉列表,否则 state 字段应显示为空输入文本框。

实际结果:

每当美国被选中为国家/地区时,它就会按照预期的工作,即显示状态选择下拉目和选择非美国国家显示状态字段为空。但是,在页面重新加载并再次执行相同的步骤后: 1)美国被选为国家,状态下拉菜单正在显示。 2)选择一个非美国国家,该国家字段将填充预先选择的美国州值,而不是将其显示为空/null。

【问题讨论】:

  • 那是因为你有点使用tms_state 作为value 两者的绑定。你可以在 .subscribe 中添加条件检查以使 tms_state 在你选择美国以外的地方时为空。

标签: knockout.js


【解决方案1】:

我不完全确定我是否在这里得到它,但你似乎过于复杂了,这是你所追求的吗?

console.clear();
function myViewModel() {
	var self = this;
  self.countries = ko.observableArray([{name:'US', abb: 'US'}, {name: 'Canada', abb: 'CA'}]);  
  self.states = ko.observableArray([{name:'Alabama',abb:'AL'},{name:'Alaska',abb:'AK'}]);
  self.selectedCountry = ko.observable();
  self.selectedState = ko.observable();
  
  self.selectedCountry.subscribe(function () {
  	self.selectedState('');
  });
  
  self.insertDataUs = function () {
  	var country = { name: 'US', abb: 'US', state: { name: 'Alaska', abb: 'AK' }};
    self.selectedCountry(country.abb);
    self.selectedState(country.state.abb);
  };
  
  self.insertDataOther = function () {
  var country = { name: 'Canada', abb: 'CA', state: { name: 'Randomstate', abb: 'RS' }};
  	self.selectedCountry(country.abb);
    self.selectedState(country.state.abb);
  };
};

ko.applyBindings(new myViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="options: countries, value: selectedCountry, optionsText: 'name', optionsValue: 'abb', optionsCaption: 'choose'"></select>
<!-- ko if: selectedCountry() != null && selectedCountry() == 'US' -->
<select data-bind="options: states, value: selectedState, optionsText: 'name', optionsValue: 'abb', optionsCaption: 'choose'"></select>
<!-- /ko -->
<!-- ko if: selectedCountry() != null && selectedCountry() != 'US' -->
<input type="text" data-bind="textInput: selectedState" />
<!-- /ko -->
<br />
<!-- ko with: selectedCountry -->
country: <span data-bind="text: _.find($root.countries(), (items) => { return items.abb == $data }).name"></span><br />
<!-- /ko -->
<!-- ko with: selectedState -->
state: <span data-bind="text: $root.selectedCountry() == 'US' ? _.find($root.states(), (items) => { return items.abb == $data }).name : $data"></span><br />
<!-- /ko -->
<button data-bind="click: insertDataUs">us data</button> <button data-bind="click: insertDataOther">other data</button>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多