我正在学习KO并试图创建一个简单的列表项添加/删除。但我有以下问题。
Q1:如果您单击添加而不输入名称,则您刚添加的项目将以result
作为名称。为什么以及如何在允许空作为有效输入时阻止它?
Q2:我想使用<pre>
标签来显示当前视图模型的JSON,但它没有显示任何内容。但按钮显示了一些东西。 我想出了这个。我需要使用ko.toJSON($data, null, 4)
。
问题3:它与Q2有关,按钮显示了一些内容,但它显示的内容似乎很奇怪。输入几个项目后,单击debug
按钮。您将看到视图模型中的所有项目都被您更改的最后一项替换。
这是fiddle。
CSS:
input[type=text], select {
width:100px;
}
JS:
function foodie() {
this.name;
this.food;
}
function foodieApp() {
var self = this;
self.foodies = ko.observableArray();
self.foodieToAdd = ko.observable(new foodie());
self.addFoodie = function () {
this.foodies.push(this.foodieToAdd());
};
self.delFoodie = function (foodieToDel) {
self.foodies.remove(foodieToDel);
};
self.debug = function () {
alert(ko.toJSON(self, null, 4));
};
}
var app = new foodieApp();
ko.applyBindings(app);
HTML:
<table>
<thead>
<tr>
<td>Foodie's Name
<br/>
<input type=text data-bind='value: foodieToAdd().name' />
</td>
<td>Foodie's Food
<br/>
<select data-bind='value: foodieToAdd().food'>
<option value=apple>Apple</option>
<option value=banana>Banana</option>
<option value=cherry>Cherry</option>
</select>
</td>
<td>
<input type=button value=Add data-bind='click: addFoodie' />
</td>
</tr>
</thead>
<tbody data-bind='foreach: foodies'>
<tr>
<td>
<input type=text data-bind='value: name' />
</td>
<td>
<select data-bind='value: food'>
<option value=apple data-bind>Apple</option>
<option value=banana>Banana</option>
<option value=cherry>Cherry</option>
</select>
</td>
<td>
<input type=button value=del data-bind='click: $parent.delFoodie' />
</td>
</tr>
</tbody>
</table>
<input type=button value=debug data-bind='click: debug' />
<!-- why the following <pre> tag is empty? -->
<pre data-bind='text: ko.toJSON(app, null, 4)'></pre>
答案 0 :(得分:2)
这是一个更新的小提琴:http://jsfiddle.net/jearles/TgD6a/3/
-
foodie
对象app
不是ViewModel的一部分 - 它是ViewModel。使用$root
访问顶级ViewModel foodieToAdd
的方式有关。基本上你只创建一个实例,因此Knockout不断地反复添加相同的对象。因为你没有可观察的属性,所以敲门不会更新UI。在我的小提琴中,我改变了foodieToAdd
的定义方式。它现在只是一个标准对象,具有两个可观察的属性。当您单击add
时,它会克隆foodieToAdd
以在observableArray中创建新条目。
编辑:请参阅下面的评论,了解为什么淘汰赛正在升级result
。
-
function foodie(foodie) {
this.name = ko.observable(foodie ? foodie.name() : '');
this.food = ko.observable(foodie ? foodie.food() : '');
}
function foodieApp() {
var self = this;
self.foodies = ko.observableArray();
self.foodieToAdd = new foodie();
self.addFoodie = function () {
this.foodies.push(new foodie(this.foodieToAdd));
};
self.delFoodie = function (foodieToDel) {
self.foodies.remove(foodieToDel);
};
self.debug = function () {
alert(ko.toJSON(self, null, 4));
};
}
var app = new foodieApp();
ko.applyBindings(app);