javascript - 从 Knockout 可观察数组中删除表中的选定行

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

好吧,我有工作代码,可以通过选中的复选框删除选定的行。但是,我遇到了强制在任何给定时刻只能检查一个单选按钮的问题。我的第一种方法是将点击事件绑定(bind)到每个单选按钮,如果它被点击,它会循环遍历可观察数组并将所有标记为“false”。然后它只是将触发事件的项目的标志翻转为 true。我知道这不是最好的方法,但我对 knockout 缺乏光彩的了解迫使我走这条路……即使这种方法在 atm 上不起作用。谁能阐明我做错了什么或如何正确连接它?

表格的html

                <table class="accountGroups information" id="tblAccountGroups">
                <tr>
                    <td width="125px;" style="font-weight: bold;">StandardAccountNo</td>
                    <td width="125px;" style="font-weight: bold; text-align: center;">Primary</td>
                    <td style="font-weight: bold;">Effective Date</td>
                    <td style="font-weight: bold;">End Date</td>
                    <td style="font-weight: bold;">Remove</td>
                </tr>
                <!-- ko foreach: NewAccountGroupDetails-->
                <tr id="Model.NewAccountGroupDetails[0].AccountGroupName" class="acctgrp-row">
                    <td>
                        <div>
                            <input style="width: 100%;" data-bind="value: StandardAccountNo, attr: {name: 'NewAccountGroupDetails[' + $index() + '].StandardAccountNo'}" />
                        </div>
                    </td>
                    <td>
                        <div style="text-align:center;">
                            <input style="width:100%;" type="radio" data-bind="value: IsPrimary, attr: {name: 'NewAccountGroupDetails[' + $index() + '].IsPrimary'}, click: $parent.markIsPrimary" />
                        </div>
                    </td>
                    <td>
                        <div>
                            <input style="width:125px;" class="datepicker" data-bind="value: EffectiveDate, attr: {name: 'NewAccountGroupDetails[' + $index() + '].EffectiveDate'}" readonly="readonly" />
                        </div>
                    </td>
                    <td>
                        <div>
                            <input style="width:125px;" class="datepicker" data-bind="value: EndDate, attr: {name: 'NewAccountGroupDetails[' + $index() + '].EndDate'}" readonly="readonly" />
                        </div>
                    </td>
                    <td>
                        <div style="text-align:center;">
                            <input type="checkbox" data-bind="checked: markedForDeletion, attr: {name: 'NewAccountGroupDetails[' + $index() + '].MarkedForDeletion'}" />
                        </div>
                    </td>
                </tr>
                <!-- /ko -->
            </table>

下面的 JS 为页面提供动力

////VIEW MODEL FOR KNOCKOUT////
var Detail = function () {
    this.StandardAccountNo = ko.observable('');
    this.IsPrimary = ko.observable(false);
    this.EffectiveDate = ko.observable(formattedDate(new Date()));
    this.EndDate = ko.observable(formattedDate(new Date()));
    this.markedForDeletion = ko.observable(false);
};

var ViewModel = function () {
    var rawList = '@Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model.NewAccountGroupDetails))';
    this.NewAccountGroupDetails = ko.observableArray(convertJSONToKoObservableObject($.parseJSON(rawList)));
    this.NewAccountGroupDetails.push(new Detail());

    this.deleteMarkedItems = function () {
        this.NewAccountGroupDetails.remove(function (item) {
            return item.markedForDeletion();
        });
    };

    this.markIsPrimary = function () {
        for (i = 0; this.NewAccountGroupDetails().length > 0; i++) {
            this.NewAccountGroupDetails[i].IsPrimary(false);
        }
        return item.IsPrimary(true);
    };

    this.addNew = function () {
        this.NewAccountGroupDetails.push(new Detail());

        $('.datepicker').each(function (i, obj) {
            $(obj).datepicker({ changeYear: true, changeMonth: true });
        });
    }
};

ko.applyBindings(new ViewModel());

function convertJSONToKoObservableObject(json) {
    var ret = [];
    $.each(json, function (i, obj) {
        var newOBJ = {};
        for (prop in obj) {
            newOBJ[prop] = ko.observable(obj[prop]);
        }
        ret.push(newOBJ);
    });

    return ret;
}

一旦我的页面按照我想要的方式工作,我将研究语法改进,例如数组的 ko 映射库。

最佳答案

在您的 View 模型中,像这样构建删除按钮:

viewModel.remove = function (row) {
    console.log(row);
    viewModel.NewAccountGroupDetails.remove(row);
};

现在,当前上下文作为第一个参数传递给 knockout 中的任何回调。因此,如果您添加带有 data-bind="click: $parent.remove" 的按钮, 它会调用 viewModel.remove与行上下文一起工作。

<tr ...>
    ...
    <td>
        <button data-bind="click: $parent.remove">Remove</button>
    </td>
</tr>

关于javascript - 从 Knockout 可观察数组中删除表中的选定行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27004064/

相关文章:

javascript - 更改 CSS3 透视动画的轴

javascript - $index 对于所有使用 dir-paginate 的页面都是固定的

当我向下滚动时,Jquery 在 div 中淡出

asp.net-mvc - 如何外包 ASP.NET MVC 应用程序的设计?

c# - Entity Framework 代码第一个一对多级联错误

javascript - 如何检测我是否已删除文本区域内的多行

javascript - 如何将文本放在同时调整大小的调整大小图像上?

javascript - Rails 4.2 - 链接以在 302 中使用 Javascript 结果创建操作

javascript - 为什么 parseInt(key) === NaN 总是求值为 false

c# - 显示来自mysql数据库的数据