与KnockoutJS项目选择MVC视图 [英] Item selection MVC view with KnockoutJS

查看:85
本文介绍了与KnockoutJS项目选择MVC视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个通用的ASP.net MVC视图。用户界面应显示从服务器加载数据可用,选择项目列表(基本上字符串列表)。用户可以更改到列表中即可以从可用项目列表中的新项目,也可以删除选择列表中的项目。

我想用KnockoutJS它作为采取结合的优势做。

我设法完成它高达一点一切工作,除了表示在视图可用列表被初始化为选中选定的项目。例如。 如下所示

我试过各种选项(<一个href=\"http://stackoverflow.com/questions/6736136/working-with-a-list-of-checkboxes-in-knockoutjs\">using模板(最接近我想要实现),的经过ATTR 可能的选项 ),问题是,如果我管理,以显示项目查了一些其他功能中断。试图定义一个模板,但不能让它在我的情况下工作。

HTML

 &LT; D​​IV CLASS ='moverBoxOuter'&GT;
&LT; D​​IV ID ='contactsList'&GT;
    &LT;跨度数据绑定=可见:availableItems()长度大于0。&GT;可用国家:LT; / SPAN&GT;
    &LT; UL数据绑定=的foreach:availableItems,可见:availableItems()长度大于0&GT;
        &LT;立GT;
            &LT;输入类型=复选框数据绑定=的CheckedValue:$数据,检查:$ root.selectedItems/&GT;
            &LT;跨度数据绑定=TEXT:标题为&GT;&LT; / SPAN&GT;
        &LT; /李&GT;
    &LT; / UL&GT;    &LT;跨度数据绑定=可见:selectedItems()长度大于0。&GT;选择国家:LT; / SPAN&GT;    &LT; UL数据绑定=的foreach:selectedItems,可见:selectedItems()长度大于0&GT;
        &LT;立GT;
            &LT;跨度数据绑定=TEXT:标题为&GT;&LT; / SPAN&GT;
            &LT; A HREF =#数据绑定=点击:$ parent.removeItem&GT;删除&LT; / A&GT;
        &LT; /李&GT;
    &LT; / UL&GT;
&LT; / DIV&GT;

JS:

  VAR initialData = [
    {
        availableItems:
          {标题:美国,isSelected:真正},
          {标题:加拿大,isSelected:假},
          {标题:印度,isSelected:假}]
    },
    {
        selectedItems:
          {称号:美国},
          {称号:加拿大}
        ]
    }
];功能项目(titleText,isSelected){
    this.title = ko.observable(titleText);
    this.isSelected = ko.observable(isSelected);
}VAR SelectableItemViewModel =功能(项){
    //数据
    VAR自我=这一点;    self.availableItems = ko.observableArray(ko.utils.arrayMap(项目[0] .availableItems,功能(项目){
        返回新项目(item.title,item.isSelected);
    }));    self.selectedItems = ko.observableArray(ko.utils.arrayMap(项目[1] .selectedItems,功能(项目){
        返回新项目(item.title,item.isSelected);
    }));    //操作
    self.selectItem =功能(项目){
        self.selectedItems.push(项目);
        item.isSelected(item.isSelected()!);
    };    self.removeItem =功能(removedItem){
        self.selectedItems.remove(removedItem);
        $。每个(self.availableItems,函数(项目){
            如果(item.title === removedItem.title){
                item.isSelected = FALSE;
            }
        });
    };
}VAR VM =新SelectableItemViewModel(initialData);$(文件)。就绪(函数(){
    ko.applyBindings(VM);
});

能否请你帮忙,看到的jsfiddle如下:

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

**更新:跟进以下问题**

其后续问题:

我需要在相同的用户界面例如添加一个组合框美国的状态。可使用的项目县,基于用户选择的状态组合,我需要筛选出县。我从使用AJAX和所有成功的服务器获取数据,但所显示的列表不清爽。我期待有正确的设置绑定,如果我们改变视图模型中可观察到的阵列,用户界面​​改变。我试图迫使改变availableItems但它只是显示所有项目。请看看你能不能在那里我更新视图模型观察到的阵列点以下code中的问题。

 函数multiselect_change(){            的console.log(事件:openmultiselect_change);            变种selectedState = $(#stateDropdownSelect)VAL();            。VAR propertyName的= $(#属性名)VAL();
            VAR searchId = @ M​​odel.SearchId;
            VAR物品;            VAR模型= {propertyName的:propertyName的,searchId:searchId,Statename的:selectedState};
            $阿贾克斯({
                网址:'@ Url.Action(GetFilterValues​​,搜索),
                的contentType:应用/ JSON的;字符集= UTF-8,
                输入:POST,
                数据类型:HTML,
                数据:JSON.stringify(模型)
            })
                .success(功能(结果){
                    调试器;                    项目= JSON.parse(结果);                    vm.availableItems(items.AvailableItems);                    //vm.availableItems.valueHasMutated();                    // VAR项目=的document.getElementById('availableItemId');
                    //ko.cleanNode(item);
                    //ko.applyBindings(vm,项目);                    vm.filter(selectedState);
                })
                .error(功能(XHR,状态){
                    警报(状态);
                });
    }


解决方案

由于user3426870提到的,您需要更改传递给托运结合布尔值。

 &LT;输入类型=复选框数据绑定=的CheckedValue:$数据,检查:isSelected/&GT;

另外,我不认为你需要在初始数据selectedItems。

而不是在视图模型,你可以这样做:

  self.selectedItems = ko.computed(函数(){
            返回ko.utils.arrayFilter(self.availableItems()函数(项目){
                返回item.isSelected();
            });
        });

I am trying to implement a generic ASP.net MVC view. The UI should display a list of available and selected items loading data (basically list of string) from server. User can make changes into the list i.e. can select new items from available item list and also can remove items from selected list.

I wanted to do it using KnockoutJS as to take advantage of binding.

I manage to complete it upto the point everything is working except showing selected item as checked when the view is initialized in available list. E.g. As Shown Here

I tried various options (using template (closest to what I want to achieve), Checked attr, possible options), the issue is if I manage to display item checked some other functionality breaks. Tried defining a template but could not get it to work in my case.

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

Could you please help, see jsfiddle below:

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

**Update: Follow up question below **

Its followup question:

I need to add a combobox on same UI e.g. for US state. The available items are counties, based on user selection in state combo I need to filter out counties. I am getting data from server using AJAX and its all successful BUT the displayed list is not refreshing. I was expecting having binding setup correctly, if we change the observable array in viewmodel, the UI should change. I tried forcing change to availableItems but it just display all items. Please see if you can spot the problem in below code where I am updating ViewModel observable array.

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

解决方案

As user3426870 mentioned, you need to change the value you passed to the checked binding to boolean.

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

Also, I don't think you need to have selectedItems in the initial data.

Instead in the viewModel, you can do something like:

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

这篇关于与KnockoutJS项目选择MVC视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆