敲除绑定的选择下拉列表,默认文本和两种方式值绑定



我有一个与Typescript ViewModel结合的选择控件,Select具有默认选项("选择..."),该选项应在页面加载中显示。如果将ViewModel通过了初始阶段,则应将默认值作为选定选项覆盖。

我可以将初始期限传递给模型,并通过回调在父型模型上使用该模型以保存表单上的条目。但是,该值绑定无法与控件一起使用,并且"选择..."文本仍显示在控件中,而不是初始期间标签为选定选项。

查看

<div id="customPeriodSelection" data-bind="with: customPeriodSelection">
<select id="periodSelect" class="form-control" data-bind="value: selectedOption, event: { change: onChange }">
    <option>@Labels.SelectDD</option>
    <!--ko foreach: {data: customGroups}-->
    <optgroup data-bind="attr: { label: label}">
        <!--ko foreach: {data: customPeriods}-->
        <option data-bind="text: $data.label, value: $data"></option>
        <!-- /ko -->
    </optgroup>
    <!-- /ko -->
</select>

打字稿

export class CustomPeriod {
    constructor(
        public start: Iso8601DateString,
        public end: Iso8601DateString,
        public label: string) { }
    identifier = () => {
        return this.start + "-" + this.end;
    }
    static mapCustomPeriod = (period: any) => {
        return new CustomPeriod(
            period.startDate,
            period.endDate,
            period.label
        )
    }
}
export class CustomPeriodSelection {
    customFrequencyId: number;
    customPeriods: KnockoutObservableArray<CustomPeriod> = ko.observableArray([]);
    selectedOption: KnockoutObservable<any> = ko.observable();
    constructor(
        customFrequencyId: number,
        initialPeriod: any,
        public callback: (customPeriod: CustomPeriod) => void
    ) {
        var base = this;
        this.customFrequencyId = customFrequencyId;
        Verco.Services.GetData("GetPeriods", {
            frequency: customFrequencyId
        },
            function (result: any[]) {
                if (result.length > 0) {
                    _.each(result, function (customPeriod: any) {
                        base.customPeriods.push(CustomPeriod.mapCustomPeriod(customPeriod));
                    })
                }
            });
        if (initialPeriod !== null) {
            var mappedPeriod = CustomPeriod.mapCustomPeriod(initialPeriod);
            this.selectedOption(mappedPeriod);
            this.callback(this.selectedOption());
        }
    }
    customGroups: KnockoutComputed<any[]> = ko.computed(() => {
        var groupedList = _.groupBy(this.customPeriods(), function (customPeriod: CustomPeriod) {
            return Verco.Format.FormatDate(customPeriod.end, DateFormats.Year);
        });
        return _.map(groupedList, function (customPeriod: any) {
            return {
                label: Verco.Format.FormatDate(customPeriod[0].end, DateFormats.Year),
                customPeriods: customPeriod
            }
        });
    });
    onChange = () => {
        if (this.callback !== null) {
            this.callback(this.selectedOption());
        }
    };
}

初始期间通过

{customFrequencyId: 1008, startDate: "2017-01-01T00:00:00Z", endDate: "2017-01-28T00:00:00Z", label: "P1 2017"}

映射到...

CustomPeriod {start: "2017-01-01T00:00:00Z", end: "2017-01-28T00:00:00Z", label: "P1 2017"}

所以我的问题是..在一段时间内传递时,如何将其映射到上面的类型并将其分配给可观察到的"选定",我是否使控件显示正确的选择?定制版上的所有单个属性是否需要可观察到?

我从瑞安·尼梅耶(Ryan Niemeyer)操纵选项作为可观察到的选项时已经看过这一点,我是否需要用类似的构建总体数组的方式替换计算的方法?我已经尝试过,但是没有成功。

我认为您遇到的问题是您要选择的默认值不在可用选项列表中。每次调用mapcustomperiod时,都会创建一个新对象。即使该对象的内容与列表中一个对象的内容相同,对象本身是两个完全不同的对象实例,并且不是等效的。

在填充选项列表之后,请尝试设置默认值,并通过循环浏览现有选项以找到符合您要定义"等于"的任何标准的选项来设置它。

Verco.Services.GetData("GetPeriods", {
        frequency: customFrequencyId
    },
        function (result: any[]) {
            if (result.length > 0) {
                _.each(result, function (customPeriod: any) {
                    base.customPeriods.push(CustomPeriod.mapCustomPeriod(customPeriod));
                });
                base.setValueByLabel(initialPeriod.label); //set default via label
            }
        });
...
this.setValueByLabel = function(label){
    for(var i=0; i<base.customGroups().length; i++){
        var group = base.customGroups()[i];
        for(var j=0; j<group.customPeriods.length; j++){
            var item = group.customPeriods[j];
          if(item.label === label){
                base.selectedOption(item);
              return;
          }
      }
  }
}

处理空状态应该就像在绑定的选项上设置 optionsCaption一样简单。

<select data-bind="options: availableCountries,
                   optionsText: 'countryName',
                   value: selectedCountry,
        >>-------> optionsCaption: 'Choose...'"></select>

http://knockoutjs.com/documentation/options-binding.html

最新更新