Javascript 使用注释循环选项时取消重置值

Javascript 使用注释循环选项时取消重置值,javascript,html,knockout.js,frontend,Javascript,Html,Knockout.js,Frontend,示例问题: 在knockout中,我有一个要在其中使用optgroups的选择框。此选择框可以根据您当前所在的“部分”进行重新设置。我发现,由于knock执行其绑定顺序的方式,出现了以下问题: HTML: <div> <a href="#" data-bind="click: page1">Section 1</a> <a href="#" data-bind="click: page2">Section 2

示例问题:

在knockout中,我有一个要在其中使用optgroups的选择框。此选择框可以根据您当前所在的“部分”进行重新设置。我发现,由于knock执行其绑定顺序的方式,出现了以下问题:

HTML:

    <div>
        <a href="#" data-bind="click: page1">Section 1</a>
        <a href="#" data-bind="click: page2">Section 2</a>
    </div>
    <hr/>
    <div data-bind="with: activepage">
        <select data-bind="value: selectedItem">
            <optgroup label="Items">
                <!-- ko foreach: items()  -->
                <option data-bind="value: $data, text: $data"></option>
                <!-- /ko -->
            </optgroup>
            <optgroup label="Constants">
                <option value="foo">foo</option>
            </optgroup>
        </select>
        <br/><br/>
        Selected Item:&nbsp;<span data-bind="text: selectedItem"></span>
    </div>
        function SubPageViewModel(name) {
            this.name = name;
            this.items = ko.observableArray(["one", "two", "three"]);
            this.selectedItem = ko.observable();
        }

        function PageViewModel() {
            this.pages = [new SubPageViewModel("page1"), new SubPageViewModel("page2")];
            this.activepage = ko.observable(this.pages[0]);

            this.page1 = function() { this.activepage(this.pages[0]); }
            this.page2 = function() { this.activepage(this.pages[1]); }
        }

        ko.applyBindings(new PageViewModel());
  • 因为我正在使用注释foreach来填充一个选择框,所以即使选择了一个项目,数据最初也会将下拉列表的selected值绑定为null

  • 当您离开当前节并向后导航时,所选值将重置为null

我认为这是因为knockout是在注释foreach填充选定框之前绑定选定值,因此其值设置为null。然后,一旦选择框被填充,则不会触发更新以更新所选值


如何解决此问题?

关于导致问题的绑定顺序,您是对的。不过,有一种方法可以强制子体绑定首先发生。您可以通过创建一个只绑定子体的自定义绑定,并将该绑定添加到
绑定之前来实现这一点

以下是自定义绑定:

ko.bindingHandlers.bindContents = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.applyBindingsToDescendants(bindingContext, element);
        return { controlsDescendantBindings: true };
    }
};
以下是您将如何使用它:

<select data-bind="bindContents: true, value: selectedItem">


下面是您使用此方法(以及其他清理)的示例:

关于导致问题的绑定顺序,您是对的。不过,有一种方法可以强制子体绑定首先发生。您可以通过创建一个只绑定子体的自定义绑定,并将该绑定添加到
绑定之前来实现这一点

以下是自定义绑定:

ko.bindingHandlers.bindContents = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.applyBindingsToDescendants(bindingContext, element);
        return { controlsDescendantBindings: true };
    }
};
以下是您将如何使用它:

<select data-bind="bindContents: true, value: selectedItem">


以下是您使用此方法(以及其他清理方法)的示例:

请不要使用URL缩写来回避在问题中添加代码的问题。在问题中包含代码。使用JSFIDLE的方式真奇怪。所有javascript都在HTML窗格中。@Tyrsius:同意。这里有一个不确定这是否有帮助的例子,但这里有一个正在工作的optgroup示例,它似乎很有效。请不要使用URL缩写来绕过为您的问题添加代码。在问题中包含代码。使用JSFIDLE的方式真奇怪。所有javascript都在HTML窗格中。@Tyrsius:同意。下面是一个不确定这是否有帮助的示例,但下面是一个正在工作的optgroup示例,它似乎可以工作