我在嵌套的 foreach 中添加和删除时遇到问题。在这个例子中,我们有一个有很多房间的房子。每个房间都有许多家具。到目前为止,使用这段代码,我可以让数据正确显示并可以添加和删除房间,但我无法添加或删除家具。
HTML
//Other House fields work as expected above this section
<div data-bind='foreach: rooms'>
<button type="button" data-bind='visible: $root.rooms().length > 1, click: $root.removeRoom'> Remove Room </button>
<p> Room Name</p>
<input type="text" data-bind="value: name"></input>
//with: appears to work the same as a foreach -- neither seem to work
<div data-bind="with: furnitures">
<button type="button" data-bind='click: $root.rooms().furnitures().removeFurniture'> Remove Furniture </button>
<p> Furniture Name</p>
<input type="text" data-bind="value: name"></input>
</div>
<button type="button" data-bind='click: $root.rooms().furnitures().addFurniture'> Add Furniture </button>
</div>
<button type="button" data-bind='click: $root.addRoom'> Add Room </button>
JavaScript
var HouseModel = function(rooms) {
var self = this;
self.rooms = ko.observableArray(rooms);
// Not sure what to put here for Furniture because each room array item has an array of many furnitures
// ROOM MANAGEMENT ==========================
self.addRoom = function() {
self.rooms.push({
name:"",
furnitures[]: ""
});
};
self.removeRoom = function(room) {
self.rooms.remove(room);
};
// FURNITURE MANAGEMENT ==========================
// Not sure where this goes
self.addFurniture = function() {
self.furnitures.push({
name: ""
});
};
self.removeFurniture = function(furniture) {
self.furnitures.remove(furniture);
};
};
var viewModel = new HouseModel(rooms); // rooms are the pre-existing rooms and their furniture, in JSON format
ko.applyBindings(viewModel);
这方面的主要问题可能与按钮数据绑定(bind)的上下文以及模型的编码方式有关。缺少或错误的东西。
感谢您的想法。
更新 这是问题的一个 fiddle : http://jsfiddle.net/zhLf1n61/
资源:
- > Knockout nested view model (这个例子是不同的,因为它没有嵌套 View 模型)
- > Knockout.JS official -working with collections (我发现这很难适用于我的情况)
最佳答案
更新了 javascript...
主要入口点是 HouseModel...房屋有房间(以及移除和添加它们的方法),房间有家具(有添加和移除它们的方法)。一切都与封装和范围有关。
在这里 fiddle :http://jsfiddle.net/zqwom7kd/
var initialData = [{
"name": "Living Room",
"furnitures": [{
"name": "Bookshelf",
"size": "Medium"
}]
}, {
"name": "Bedroom",
"furnitures": [{
"name": "Bed",
"size": "Large"
}, {
"name": "Night Table",
"size": "Small"
}, {
"name": "Jacuzzi",
"size": "Large"
}]
}];
var Furniture = function(data) {
var self = this;
self.name = ko.observable('');
self.size = ko.observable('');
if (typeof data !== 'undefined') {
self.name(data.name);
self.size(data.size);
}
}
var Room = function(name, furnitures) {
var self = this;
self.name = ko.observable(name);
self.furnitures = ko.observableArray([]);
if (typeof furnitures !== 'undefined') {
$.each(furnitures, function(i, el) {
self.furnitures.push(new Furniture({name: el.name, size: el.size}));
});
}
self.removeFurniture = function(furniture) {
self.furnitures.remove(furniture);
};
self.addFurniture = function() {
console.log("added");
self.furnitures.push(new Furniture({name: '', size: ''}));
};
};
var HouseModel = function (rooms) {
var self = this;
self.save = function() {
console.log("do stuff");
};
self.lastSavedJson = ko.observable('');
self.rooms = ko.observableArray([]);
if (typeof rooms !== 'undefined') {
$.each(rooms, function(i, el) {
self.rooms.push(new Room(el.name, el.furnitures));
});
}
self.addRoom = function(name) {
self.rooms.push(new Room(name));
};
self.removeRoom = function (room) {
self.rooms.remove(room);
};
};
ko.applyBindings(new HouseModel(initialData));
HTML
<h2>House Components</h2>
<div id='roomsList'>
<table class='roomsEditor'>
<tr>
<th>Room Name</th>
<th>Furnitures</th>
</tr>
<tbody data-bind="foreach: rooms">
<tr class="well">
<td valign="top">
<input type="text" data-bind='value: name' />
<div> <button class="btn btn-danger" data-bind='click: $root.rooms.removeRoom'>Remove Room</button>
</div>
</td>
<td>
<table>
<tbody data-bind="foreach: furnitures">
<tr>
<td>
<input type="text" data-bind='value: name' />
</td>
<td>
<input type="text" data-bind='value: size' />
</td>
<td>
<button class="btn btn-danger" data-bind='click: $parent.removeFurniture'>Delete Furniture</button>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-success" data-bind='click: addFurniture'>Add Furniture</button>
</td>
</tr>
</tbody>
</table>
</div>
<p>
<button class="btn btn-success" data-bind='click: $root.rooms.addRoom'>Add Room</button>
<button data-bind='click: save, enable: rooms().length > 0'>Save to JSON</button>
</p>
<textarea data-bind='value: lastSavedJson' rows='5' cols='60' disabled='disabled'></textarea>
关于javascript - knockout 嵌套 foreach 添加和删除不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29597014/