Knockout添加和编辑observableArray冲突

时间:2015-05-06 02:57:37

标签: javascript knockout.js

我有一个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);
});

2 个答案:

答案 0 :(得分:0)

我找到了问题的原因,我不得不将我使用observableArray所做的每一项更改镜像到我的列表中。

bash -c your_bash_file.sh

如果有人碰到类似的问题,这是fiddle

答案 1 :(得分:0)

subscribe 处理程序self.selectedDeduction.subscribe中,当您应添加loanDeductions的新实例时,您将向deductionLine列表中添加一个对象就像你宣布self.loanDeductions时一样。

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

更改订阅处理程序以推送new deductionLine(...),您将看到差异。