javascript - 使用 KnockoutJS 的项目选择 MVC View

标签 javascript jquery asp.net-mvc knockout.js

我正在尝试实现一个通用的 ASP.net MVC View 。 UI 应显示从服务器加载数据的可用和选定项目的列表(基本上是字符串列表)。用户可以对列表进行更改,即可以从可用项目列表中选择新项目,也可以从选定列表中删除项目。

我想使用 KnockoutJS 来实现这一点,以利用绑定(bind)。

我设法完成它,到目前为止一切正常,除了在可用列表中初始化 View 时将所选项目显示为选中状态之外。例如。 As Shown Here

我尝试了各种选项( using template (closest to what I want to achieve)Checked attrpossible options ),问题是我是否设法显示项目检查了一些其他功能中断。尝试定义一个模板,但无法让它在我的情况下工作。

HTML:

<div class='moverBoxOuter'>
<div id='contactsList'>
    <span data-bind="visible: availableItems().length > 0">Available countries: </span>
    <ul data-bind="foreach: availableItems, visible: availableItems().length > 0">
        <li>
            <input type="checkbox" data-bind="checkedValue: $data, checked: $root.selectedItems" />
            <span data-bind="text: title"></span>
        </li> 
    </ul>

    <span data-bind="visible: selectedItems().length > 0">Selected countries: </span>

    <ul data-bind="foreach: selectedItems, visible: selectedItems().length > 0">
        <li>
            <span data-bind="text: title"></span>
            <a href="#" data-bind="click: $parent.removeItem">Delete</a>
        </li> 
    </ul>
</div>

JS:

    var initialData = [
    {
        availableItems: [
          { title: "US", isSelected: true },
          { title: "Canada", isSelected: false },
          { title: "India", isSelected: false }]
    },
    {
        selectedItems: [
          { "title": "US" },
          { "title": "Canada" }
        ]
    }
];

function Item(titleText, isSelected) {
    this.title = ko.observable(titleText);
    this.isSelected = ko.observable(isSelected);
}

var SelectableItemViewModel = function (items) {
    // Data
    var self = this;

    self.availableItems = ko.observableArray(ko.utils.arrayMap(items[0].availableItems, function (item) {
        return new Item(item.title, item.isSelected);
    }));

    self.selectedItems = ko.observableArray(ko.utils.arrayMap(items[1].selectedItems, function (item) {
        return new Item(item.title, item.isSelected);
    }));

    // Operations
    self.selectItem = function (item) {
        self.selectedItems.push(item);
        item.isSelected(!item.isSelected());
    };

    self.removeItem = function (removedItem) {
        self.selectedItems.remove(removedItem);
        $.each(self.availableItems, function (item) {
            if (item.title === removedItem.title) {
                item.isSelected = false;
            }
        });
    };
}

var vm = new SelectableItemViewModel(initialData);

$(document).ready(function () {
    ko.applyBindings(vm);
});

您能帮忙吗,请参阅下面的 jsfiddle:

http://jsfiddle.net/sbirthare/KR4a6/6/

**更新:跟进下面的问题**

其后续问题:

我需要在同一用户界面上添加一个组合框,例如对于美国州。可用的项目是县,根据用户在州组合中的选择,我需要过滤掉县。我正在使用 AJAX 从服务器获取数据,一切都成功,但显示的列表不刷新。我期望绑定(bind)设置正确,如果我们更改 View 模型中的可观察数组,UI 应该更改。我尝试强制更改 availableItems 但它只显示所有项目。请看看您是否可以在下面的代码中发现问题,我正在更新 ViewModel 可观察数组。

function multiselect_change() {

            console.log("event: openmultiselect_change");

            var selectedState = $("#stateDropdownSelect").val();

            var propertyName = $("#PropertyName").val();
            var searchId = @Model.SearchId;
            var items;

            var model = { propertyName: propertyName, searchId: searchId, stateName: selectedState };
            $.ajax({
                url: '@Url.Action("GetFilterValues", "Search")',
                contentType: 'application/json; charset=utf-8',
                type: 'POST',
                dataType: 'html',
                data: JSON.stringify(model)
            })
                .success(function(result) {
                    debugger;

                    items = JSON.parse(result);

                    vm.availableItems(items.AvailableItems);

                    //vm.availableItems.valueHasMutated();

                    //var item = document.getElementById('availableItemId');
                    //ko.cleanNode(item);
                    //ko.applyBindings(vm, item);

                    vm.filter(selectedState);
                })
                .error(function(xhr, status) {
                    alert(status);
                });        
    }

最佳答案

正如 user3426870 提到的,您需要将传递给已检查绑定(bind)的值更改为 bool 值。

<input type="checkbox" data-bind="checkedValue: $data, checked: isSelected" />

此外,我认为您不需要在初始数据中包含 selectedItems。

相反,在 viewModel 中,您可以执行以下操作:

self.selectedItems = ko.computed(function() {
            return ko.utils.arrayFilter(self.availableItems(), function (item) {
                return item.isSelected();
            });
        });

关于javascript - 使用 KnockoutJS 的项目选择 MVC View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23285882/

相关文章:

jquery - 使用 jQuery 检测每个实例的鼠标滚动,而不是每次单击

c# - 如何告诉 [Authorize] 属性将基本身份验证与自定义消息处理程序一起使用?

javascript - 从同一页面调用两个按钮不起作用

javascript - Vaadin 应用程序中发出蜂鸣声

javascript - npm 运行开发脚本错误

javascript - 为什么我不能在闭包中访问局部变量

javascript - 如何使用 AJAX JSON 将多个变量从 Javascript 传递到 PHP?

javascript - 内联 onclick 覆盖 JQuery click()

javascript - 在 jquery 提交函数中分配全局变量并传递给正则表达式函数

asp.net - 在我的 ASP.NET MVC 站点的区域中执行全局 View 数据的最佳方法?