我需要一个允许在编辑和查看之间切换的网格。编辑完成后,用户可以选择是否要应用或取消对已编辑行进行的更改。这是一个例子,它完全符合我的需要: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)" />
有谁知道,如何解决这个问题?任何帮助将不胜感激。
答案 0 :(得分:3)
我会使用ko.extenders分割您正在添加的状态...问题是editvalue observable在您单击编辑按钮之前不会初始化,因此在您第一次单击它时它不起作用,但在那之后确实有效。
理论上,你要做的一切都应该完全用扩展器来完成,而不是像这样添加功能。如果你只是想通过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 );
});
答案 1 :(得分:0)
我知道它已经回答了,但是这个水果的例子也是我的痛苦。我出来了:
<!-- 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已创建,但是淘汰赛并不知道它有 重新绑定。
这也适用于小于3.0的版本