【问题标题】:Knockout Add and Edit observableArray Conflict淘汰赛添加和编辑 observableArray 冲突
【发布时间】:2015-05-06 15:13:55
【问题描述】:

我有一个 observableArray,它使用 foreach 绑定显示在表中,其中值显示在文本框中。现在我要做的是在每一行上添加一个编辑链接,该链接启用/禁用其行中相应文本框的只读状态。我可以做到,但是我这样做的方式搞砸了我的添加新行(推送)功能。

这是我的代码的fiddle

尝试删除一行然后通过在下拉列表中选择它再次添加它,编辑链接以及值消失。

任何帮助将不胜感激!谢谢。

这是我的 HTML:

<table class="input-group" >
    <tbody data-bind="foreach: loanDeductions">
        <tr>
            <td><strong data-bind='text: deductionName'></strong></td>
            <td><input class="deductionCode form-control" style="text-align: right" data-bind='value: amount, valueUpdate: "afterkeydown", attr: { "readonly": getreadonlyState() }' /></td>
            <td><a href='#' data-bind='click: $parent.removeLine'>Delete</a></td>
            <td><a href="javascript:void(0);" data-bind="click: $parent.readonly"><span data-bind="text: linkText"></span></a></td>
        </tr>
    </tbody>        
</table>
<table>
    <tr>
        <td colspan="3"><select data-bind="options: loanDeductionsList(), optionsText: 'deductionName', optionsCaption: 'Choose a deduction..', value: selectedDeduction"></select></td>
    </tr>
</table>

现在这是我的脚本:

var deductionLine = function (deductionID, deductionName, amount) {
    self = this;
    self.deductionID = ko.observable(deductionID);
    self.deductionName = ko.observable(deductionName);
    self.amount = ko.observable(formatCurrency(amount));
    self.getreadonlyState = ko.observable('readonly');
    self.linkText = ko.computed(function () {
        return this.getreadonlyState() == 'readonly' ? "Edit" : "Stop Edit";
    }, self);
};

var deductionList = function (deductionID, deductionName, amount) {
    self = this;
    self.deductionID = ko.observable(deductionID);
    self.deductionName = ko.observable(deductionName);
    self.amount = ko.observable(formatCurrency(amount));
};

function LoanDeductions(deductions) {
    var self = this;
    self.loanDeductions = ko.observableArray(ko.utils.arrayMap(deductions, function (deduction) {
        return new deductionLine(deduction.deductionID, deduction.deductionName, deduction.amount)
    }));
    self.loanDeductionsList = ko.observableArray(ko.utils.arrayMap(deductions, function (deduction) {
        return new deductionList(deduction.deductionID, deduction.deductionName, deduction.amount)
    }));

    self.selectedDeduction = ko.observable();

    //edit link

    self.readonly = function () {
        if (BossBaU) {
            if (this.getreadonlyState()) {
                this.getreadonlyState(undefined);
            }
            else {
                this.getreadonlyState('readonly');
            }
        }
        else alert('Access denied!');
    }

    // adds deduction 
    self.selectedDeduction.subscribe(function (data) {
        var match = ko.utils.arrayFirst(self.loanDeductions(), function (deduction) {
            return deduction.deductionID() === data.deductionID();
        });
        if (match) {
            alert(data.deductionName() + ' already exists!');
            self.showAddDeduc(false);
        } else {
            self.loanDeductions.push({
                deductionID: data.deductionID,
                deductionName: data.deductionName,
                amount: data.amount,
            });
            self.showAddDeduc(false);
        }
    });

    //delete deduction
    self.removeLine = function (line) { self.loanDeductions.remove(line) };

};

var viewModel = new LoanDeductions(@Html.Raw(Model.CRefLoansDeductions2.ToJson()));
$(document).ready(function () {
    ko.applyBindings(viewModel);
});

【问题讨论】:

  • 您的小提琴包含与您的问题不同的代码。您是否考虑过使用堆栈片段?另外,小提琴只是简单地给出了一个脚本错误,你调试了吗?你的结果是什么?
  • 您总是忘记self = this; 行中的var 关键字。这是您需要解决的严重问题。
  • @Tomalak 谢谢,我没注意到。

标签: javascript knockout.js


【解决方案1】:

subscribe 处理程序 self.selectedDeduction.subscribe 中,当您应该添加 deductionLine 的新实例时,您正在将对象添加到 loanDeductions 的列表中,就像您在声明self.loanDeductions

或者换句话说,self.loadDeductionsdeductionLine 实例的 observableArray,然后您可以向其中添加一个具有三个属性的对象。

更改 subscribe 处理程序以推送 new deductionLine(...),您会看到不同之处。

【讨论】:

  • 谢谢,这正是我解决问题的方法。
【解决方案2】:

我找到了问题的原因,我必须将我对 observableArray 所做的每一个更改都映射到我的列表中。

var deductionLine = function (deductionID, deductionName, amount) {
    self = this;
    self.deductionID = ko.observable(deductionID);
    self.deductionName = ko.observable(deductionName);
    self.amount = ko.observable(amount);
    self.getreadonlyState = ko.observable('readonly');
    self.linkText = ko.computed(function () {
        return this.getreadonlyState() == 'readonly' ? "Edit" : "Stop Edit";
    }, self);
};

var deductionList = function (deductionID, deductionName, amount) {
    self = this;
    self.deductionID = ko.observable(deductionID);
    self.deductionName = ko.observable(deductionName);
    self.amount = ko.observable(amount);
    self.getreadonlyState = ko.observable('readonly');
    self.linkText = ko.computed(function () {
        return this.getreadonlyState() == 'readonly' ? "Edit" : "Stop Edit";
    }, self);
};

这里是fiddle,以防有人遇到类似问题。

【讨论】:

    猜你喜欢
    • 2013-02-28
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    • 2013-06-23
    • 2017-09-06
    • 2016-08-21
    相关资源
    最近更新 更多