您不能多次将绑定应用于同一元素

Alv*_*vin 4 javascript knockout.js

我有一个Bootstrap模式,每次出现时我都会使用KO绑定一个<select>下拉列表.

HTML:

<select id="album" name="album" class="form-control" data-bind="options: availableAlbums">
</select>
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

$('#uploadModal').on('show.bs.modal', (function () {
        function AlbumsListViewModel() {
            var self = this;
            self.availableAlbums = ko.observableArray([]);

            $.ajax({
                url: "../../api/eventapi/getalbums",
                type: "get",
                contentType: "application/json",
                async: false,
                success: function (data) {
                    var array = [];
                    $.each(data, function (index, value) {
                        array.push(value.Title);
                    });
                    self.availableAlbums(array);
                }
            });
        }

        ko.applyBindings(new AlbumsListViewModel());
    }));
Run Code Online (Sandbox Code Playgroud)

但是,在第二次展示时,KO会向我显示以下错误:

错误:您无法多次将绑定应用于同一元素.

Jer*_*oen 5

错误消息说明了大部分内容.您有两种选择:

  1. applyBindings页面加载时调用该函数一次.在AJAX成功函数中更新模型时,KO将自动更新View.
  2. applyBIndings在每个AJAX成功时调用该函数,但提供其他参数以告诉它要绑定到哪个元素.

最有可能的第一个选择是你正在寻找的.从呼叫中删除呼叫$('#uploadModal').on并将其置于文档加载(如果您还没有).

看看我的意思,这里有两个小提琴:

  1. 提到的错误的当前代码.
  2. 没有错误的重构版本.

后者试图尽可能接近你的初始版本(以便专注于手头的问题),并遵循这些方针:

function AlbumsListViewModel() {
    var self = this;
    self.availableAlbums = ko.observableArray([]);
}

var mainViewModel = new AlbumsListViewModel();
ko.applyBindings(mainViewModel);

$('#uploadModal').on('show.bs.modal', (function () {
    // Commenting things out to mock the ajax request (synchronously)
    var data = [{Title:'test'}];
    /*$.ajax({
        url: "../../api/eventapi/getalbums",
        type: "get",
        contentType: "application/json",
        async: false,
        success: function (data) {*/
            mainViewModel.availableAlbums.removeAll();
            var array = [];
            $.each(data, function (index, value) {
                array.push(value.Title);
            });
            mainViewModel.availableAlbums(array);
        /*}
    });*/
}));
Run Code Online (Sandbox Code Playgroud)