Knockoutjs:选择数据绑定行为

时间:2019-04-24 02:19:17

标签: knockout.js

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

我们在“国家/地区”选择下拉列表下方有一个数组作为选项:

<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);
                }
                });

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

实际结果:

无论何时将美国选为国家,它都会按预期工作,即显示州选择下拉列表,并且在选择非美国国家时将州字段显示为空。但是,在页面重新加载并再次执行相同步骤之后: 1)选择美国作为国家,州下拉列表被显示。 2)选择一个非美国国家/地区,状态字段将填充为美国的预选州值,而不是将其显示为空/空。

1 个答案:

答案 0 :(得分:0)

我不确定是否能在这里找到它,但是您似乎过于复杂了,这是您要的吗?

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>