利用基于Select Checkbox的Knockout更新Viewmodel

时间:2014-08-12 17:53:57

标签: c# javascript asp.net-mvc asp.net-mvc-4 knockout.js

我一直在研究ASP.NET MVC4 Web应用程序,并且我试图在用户端保留一些选定/取消选择项的持久数据。

基本上,我有一个HTML表,我已将其转换为Kendo Grid。通过访问后端的Oracle和SQL服务器以及在视图中强烈键入模型以便通过该模型创建和填充表来填充表/网格。我正在尝试根据是否选中了复选框来更新我的ViewModel中的ObservableArray,但是我已经旋转了很长一段时间。以下是我实施的基本框架。任何帮助将不胜感激。

HTML表:

    <table id="grid" border="1">
     <thead id="tableHead">
            <tr align="center">
                <th data-field="select" id="selectChkBox"> Select</th>
                <th data-field="model">Model</th>
                <th data-field="division">Division</th>
            </tr>
        </thead>
        <tbody id="tableBody" class="hoverTable">
            @foreach (var config in Model.Models)
            {
                <tr align="right" id="entries">
                    <td><input type="checkbox" class="chkBox" data-bind="checked: addModel" id="checkbox" value="@config.ModelName"/></td>
                    <td>@config.ModelName</td>
                    <td>@config.Division</td>
                </tr>
            }
        </tbody>
    </table>

JavaScript / Knockout ViewModel:

function PRPSSelectViewModel() {
    // Data
    var self = this;
    self.AvailableModels = ko.observableArray([]);
    self.ModelNames = ko.observableArray([]);

    // Operations
    self.addModel = function (name) {
        self.ModelNames.push(name);
    };

    self.removeModel = function (name) {
        self.ModelNames.remove(name);
    };
}

我确信已经记录了这个问题的许多变化,但是我对Knockout很新,并且尽管提供了大量的资源和示例,但仍然无法实现我想要的功能。

修改 使用简单的方法解决。我只是在我的Javascript文件中实例化了一个数组,我用它来填充模型的名称。我已经有了一些Javascript设置来触发当一个复选框被标记为在kendo网格上“选择”它时,只需抓住相应的行,我就可以使用模型名称填充数组。只要页面不刷新(并且它不应该因为我正在使用CRUD操作的模态和部分视图),我应该没问题。

2 个答案:

答案 0 :(得分:0)

请参阅documentation

  

对于复选框,KO将在参数值为true时设置要检查的元素,在false为false时取消选中。 如果你给的值实际上不是布尔值,那么它将被松散地解释。这意味着非零数字和非空对象以及非空字符串都将被解释为true,而零,空,未定义和空字符串将被解释为false。

我已经突出了你所遇到的问题 - 你使用的是函数而不是可观察的。在视图模型中添加属性:

self.isChecked = ko.observable(false);
self.isChecked.subscribe(function(newValue) {
   if (newValue == true) 
       self.addModel(<observable with model name>);
   else
       self.removeModel(<observable with model name>);
});

您应该将当前ModelName保存在视图模型中的某个位置。

在您的标记中进行此更改:

....
<td><input type="checkbox" class="chkBox" data-bind="checked: isChecked" id="checkbox" value="@config.ModelName"/></td>
....

答案 1 :(得分:0)

我最近实现了类似的行为,我的工作代码与以下代码js视图模型非常相似。请参阅此小提琴,了解完整的工作示例。 http://jsfiddle.net/sbirthare/KR4a6/19/

看看这是否有帮助。

  

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

     

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

     

var SelectableItemViewModel = function(items){       //数据       var self = this;       self.filter = ko.observable(&#34;&#34;);       self.availableItems = ko.observableArray(ko.utils.arrayMap(items [0] .availableItems,function(item){           返回新项(item.title,item.isSelected);       }));

self.selectedItems = ko.observableArray(ko.utils.arrayMap(items[1].selectedItems, function (item) {
    return ko.utils.arrayFirst(self.availableItems(), function (itm){
        return item.title == itm.title();
    });

}));

    //filter the items using the filter text
self.filteredItems = ko.dependentObservable(function () {
    debugger;
    var filter = this.filter().toLowerCase();
    if (!filter) {
        return this.availableItems();
    } else {
        return ko.utils.arrayFilter(this.availableItems(), function (item) {
            return ko.utils.stringStartsWith(item.title().toLowerCase(), filter);
        });
    }
}, self);

// Operations

self.removeItem = function (removedItem) {
    self.selectedItems.remove(removedItem);
};}
  

var vm = new SelectableItemViewModel(initialData);

     

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