我对knockout.js有些新意见,而且我无法绕过将某些操作放在可观察数组上的地方。这是我的代码:
var Building = function() {
var self = this;
self.nLocation = ko.observable();
self.nBuilding = ko.observable();
...
self.increaseLocNum = function() {
self.nLocation(self.nLocation + 1);
};
}
var Quote = function() {
var self = this;
var nQuoteID = ko.observable();
...
self.buildings = ko.observableArray([]);
self.addBuilding = function(){
...
// Build new building with next loc/building number
buildings.push();
}
...
}
ko.applyBindings(new Quote());
基本上我的报价可以有多个建筑物。每个建筑物都绑定到选项卡控件上的不同选项卡。在这些标签上有一个位置'具有增加/减少位置编号的+/-按钮的字段。
我需要使用'启用'绑定以设置+/-按钮的启用(例如,如果建筑物是最高位置编号的唯一建筑物。以下是一些简单规则的示例:
逻辑非常简单,但我在这个逻辑应遵循最佳淘汰赛的地方迷失了。
答案 0 :(得分:1)
减少函数很容易,因为个别建筑视图模型不需要知道任何外部因素来做出决定;它可以是基于其位置可观察的直接计算。增加功能比较棘手,因为它取决于集合中所有其他建筑物的状态。
这是避免子类必须知道父类的一个选项。在每个建筑物上放置一个canIncrease observable,但让父视图模型处理实际的增加/减少,以便它可以循环遍历所有子节点并在位置发生更改时更新它们的observable。
var Building = function(location) {
var self = this;
self.nLocation = ko.observable(location);
self.nBuilding = ko.observable("-Building Name Here-");
self.canIncrease = ko.observable(); //set by parent
self.canDecrease = ko.computed(function(){
//Location number can't be decreased if the building is at location 1
return self.nLocation() > 1;
});
}
var Quote = function() {
var self = this;
var nQuoteID = ko.observable();
self.buildings = ko.observableArray([new Building(1)]);
self.addBuilding = function() {
// Build new building with next loc/building number
self.buildings.push(new Building(self.highestLocation() + 1));
self.enableChildren();
}
self.highestLocation = ko.computed(function(){
var highest=0;
$.each(self.buildings(), function(key,value){ if(value.nLocation() > highest) highest = value.nLocation(); });
return highest;
});
self.increaseLocNum = function(building) {
building.nLocation(building.nLocation() + 1);
self.enableChildren();
};
self.decreaseLocNum = function(building) {
building.nLocation(building.nLocation() - 1);
self.enableChildren();
};
self.enableChildren = function(){
//Location number can't be increased if the building is the only building on the highest location
//Location number can't be increased if there is only one building
$.each(self.buildings(), function(key, building){
if(building.nLocation() === self.highestLocation() || self.buildings().length === 1){
building.canIncrease(false);
}else{
building.canIncrease(true);
}
});
}
}
ko.applyBindings(new Quote());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="button" data-bind="click: addBuilding" value="Add Building" />
<span style="margin-left: 8px;">Total Buildings: <label data-bind="text: buildings().length" /></span>
<span style="margin-left: 8px;">Highest Location: <label data-bind="text: highestLocation" /></span>
<br/>
<table>
<thead>
<tr>
<th></th>
<th>Location</th>
<th>Building Name</th>
</tr>
</thead>
<tbody data-bind="foreach: buildings">
<tr style="border: 1px solid blue;">
<td>
<input type="button" data-bind="enable: canDecrease, click: $parent.decreaseLocNum" value="-" />
<input type="button" data-bind="enable: canIncrease, click: $parent.increaseLocNum" value="+" />
</td>
<td>
<span data-bind="text: nLocation"></span>
</td>
<td>
<span data-bind="text: nBuilding"></span>
</td>
</tr>
</tbody>
</table>