【问题标题】:KnockoutJS: working example for editable gridKnockoutJS:可编辑网格的工作示例
【发布时间】:2015-07-08 19:01:32
【问题描述】:

我需要一个允许在编辑和查看之间切换的网格。编辑完成后,用户可以选择是否要应用或取消对已编辑行所做的更改。这是一个例子,它完全符合我的需要:http://jsfiddle.net/peterf/8FMPc/light/

但不幸的是,这个 JSFiddle 不适用于 KnockoutJS v. 3.2.0: http://jsfiddle.net/8FMPc/315/ 当我单击编辑按钮时,输入没有值(水果名称)。 这似乎是数据绑定的问题:

<input type="text" class="edit" data-bind="value: name.editValue, visible: $root.isItemEditing($data)"  />

有谁知道,如何解决这个问题?任何帮助将不胜感激。

【问题讨论】:

  • 你看过documentation的直播example吗?
  • 是的,我看到了。不幸的是,我需要更高级的功能(我已经更新了我的帖子)。

标签: knockout.js datagrid


【解决方案1】:

我会使用 ko.extenders 拆分您添加的状态内容...问题是可观察的 editvalue 在您单击编辑按钮之前不会初始化,因此在您第一次单击它时它不起作用,但在那之后确实有效。

理论上,您尝试做的所有事情都应该完全使用扩展程序来完成,而不是像这样添加函数。如果你只是想通过 fn 能力添加功能,我认为它们应该是完全无状态的。

小提琴:

http://jsfiddle.net/brettwgreen/zfxmac7z/

JS:

/*----------------------------------------------------------------------*/
/* Observable Extention for Editing
/*----------------------------------------------------------------------*/
ko.extenders.editable = function(target, option) {
    if (Array.isArray(target()))
        target.editValue = ko.observableArray(target().slice());
    else
        target.editValue = ko.observable(target());    
};

ko.observable.fn.beginEdit = function (transaction) {

    var self = this;
    var commitSubscription, 
        rollbackSubscription;

    self.dispose = function () {        
        // kill this subscriptions
        commitSubscription.dispose();
        rollbackSubscription.dispose(); 
    };

    self.commit = function () {
        // update the actual value with the edit value
        self(self.editValue());

        // dispose the subscriptions
        self.dispose();
    };

    self.rollback = function () {
        // rollback the edit value
        self.editValue(self());

        // dispose the subscriptions
        self.dispose();
    };

    //  subscribe to the transation commit and reject calls
    commitSubscription = transaction.subscribe(self.commit,
                                               self,
                                               "commit");

    rollbackSubscription = transaction.subscribe(self.rollback,
                                                 self,
                                                 "rollback");

    return self;
}

/*----------------------------------------------------------------------*/
/* Item Model
/*----------------------------------------------------------------------*/

function Fruit( name, colour) {
    var self = this;
    // extend to add the editable capability
    // this allows them to initialize right out of the gate
    self.name = ko.observable(name).extend({ editable: true });
    self.colour = ko.observable(colour).extend({ editable: true });
};

Fruit.prototype.beginEdit = function(transaction) {
    this.name.beginEdit(transaction);
    this.colour.beginEdit(transaction);
}


/*----------------------------------------------------------------------*/
/* View Model
/*----------------------------------------------------------------------*/
function FruitColourViewModel() {
    var self = this;

    //  data
    self.availableColours = [];
    self.fruits = ko.observableArray([]);
    self.editingItem = ko.observable();

    //  create the transaction for commit and reject
    self.editTransaction = new ko.subscribable();

    //  helpers
    self.isItemEditing = function(fruit) {
        return fruit == self.editingItem();
    };

    //  behaviour
    self.addFruit = function () {
        var fruit = new Fruit("New fruit", self.availableColours[0]);
        self.fruits.push(fruit);

        //  begin editing the new item straight away
        self.editFruit(fruit);
    };

    self.removeFruit = function (fruit) {
        if (self.editingItem() == null) {
            var answer = true; // confirm('Are you sure you want to delete this fruit? ' + fruit.name());
            if (answer) {
                self.fruits.remove(fruit)
            }
        }
    };

    self.editFruit = function (fruit) {
        if (self.editingItem() == null) {
            // start the transaction
            fruit.beginEdit(self.editTransaction);

            // shows the edit fields
            self.editingItem(fruit);
        }
    };

    self.applyFruit = function (fruit) {
        //  commit the edit transaction
        self.editTransaction.notifySubscribers(null, "commit");

        //  hides the edit fields
        self.editingItem(null);
    };

    self.cancelEdit = function (fruit) {
        //  reject the edit transaction
        self.editTransaction.notifySubscribers(null, "rollback");

        //  hides the edit fields
        self.editingItem(null);
    };

}

/*----------------------------------------------------------------------*/
/* KO Page Binding                                                      */
/*----------------------------------------------------------------------*/   
$(document).ready(function() {

    //  create the model
    var model = new FruitColourViewModel();
    model.availableColours = ["Blue", "Green", "Orange", "Red", "Yellow"];

    var initData = [
        new Fruit( "Apple", "Green"),
        new Fruit( "Banana", "Yellow"),
        new Fruit( "Orange", "Orange"),
        new Fruit( "Strawberry", "Red")
    ];

    model.fruits(initData);

    //  bind model to the html
    ko.applyBindings( model );   

});

【讨论】:

  • 完美,非常感谢您的宝贵时间,布雷特! :) 我是 KO 的新手,这对我帮助很大。我将更详细地了解扩展器。
  • 没问题...以后,直接在帖子中包含您的代码。有一个小提琴是可以的,但是这些可能会过时(链接失效),然后这个问题对未来的访问者不再有用。我通常同时做内联代码和小提琴。
【解决方案2】:

我知道它已经被回答了,但是这个水果的例子也是我的痛苦。我想出了这个:

 <!-- ko if: $root.isItemEditing($data) -->
            <input type="text" class="edit" data-bind="value: name.editValue, visible: $root.isItemEditing($data)"/>
 <!-- /ko -->

在旧版本的淘汰赛模型中更频繁地重新绑定,这就是它以前工作的原因。在较新的版本中:

在第一次评估绑定时,editValue 每个水果的可观察对象的子可观察对象( data-bind="value: name.editValue" ) 不存在。当您单击“编辑”链接时 editValue observable 已创建但淘汰赛不知道它有 重新绑定。

suggested answere

这也适用于低于 3.0 的版本

【讨论】:

    猜你喜欢
    • 2012-03-29
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    • 1970-01-01
    • 2014-12-03
    • 2013-03-30
    • 1970-01-01
    相关资源
    最近更新 更多