我有一张桌子,我填写了一些数字。每行都有一个按钮。单击此按钮后,我想在此行中减少一个计数器。怎么用淘汰赛这个?
<div class="panel panel-default">
<div class=panel-heading>Title</div>
<table class=table>
<thead>
<tr>
<th>Counter</th>
<th>Increment</th>
</tr>
</thead>
<tbody data-bind="foreach: records">
<tr>
<td data-bind="text: counter"></td>
<td> <input type="button" value="increment" data-bind=??? ></td>
</tr>
</tbody>
</table>
</div>
<script>
function AppViewModel() {
var self = this;
self.records = ko.observableArray([]);
$.getJSON("/data", function(data) {
self.records(data);
})
//function to decrement
}
ko.applyBindings(new AppViewModel());
</script>
答案 0 :(得分:1)
我会这样做:
counter
属性转换为observable并添加函数以减少计数器属性applyBindings
调用移至ajax回调,以便在加载所有内容时触发所以代码看起来像:
<tr>
<td data-bind="text: counter"></td>
<td> <input type="button" value="decrement" data-bind="click: decrement"></td>
</tr>
function AppViewModel() {
var self = this;
self.records = ko.observableArray([]);
}
var vm = new AppViewModel();
// load data from server
$.getJSON("/data", function(data) {
data.forEach( function(item) {
// make counter observable
item.counter = ko.observable(item.counter);
// add function to decrement
item.decrement = function() {
this.counter( this.counter()-1 );
}
})
// load array into viewmodel
vm.records(data);
// apply bindings when all obervables have been declared
ko.applyBindings(vm);
})
检查演示:Fiddle
答案 1 :(得分:0)
我更喜欢立即初始化并绑定我的viewmodel,但同意另一张需要观察的海报。
这是一个继续创建和绑定viewmodel的解决方案,就像在原始示例中一样,但是不是您收到的原始记录数组,而是将它们转换为自己的小模型对象,这些对象具有可观察的计数器和可以数据绑定的增量函数。这会将您的数据负载与视图模型的生命周期分离,因此如果您想添加一个按钮来加载新数据以覆盖它或类似的东西,那么它只是对getData()的另一个调用。
<!-- ... -->
<tbody data-bind="foreach: records">
<tr>
<td data-bind="text: counter"></td>
<td> <input type="button" value="increment" data-bind="click: increment" ></td>
</tr>
</tbody>
<!-- ... -->
<script>
function AppViewModel() {
var self = this;
self.records = ko.observableArray([]);
self.getData = function(){ /* ... */ };
self.getFakeData = function(){
var data = [{ counter: 1 }, { counter: 2}, { counter: 3 }];
var freshData = data.map(function(record){
return new AppRecord(record);
});
self.records(freshData);
};
}
function AppRecord(rawRecord) {
var self = this;
self.counter = ko.observable(rawRecord.counter);
self.increment = function(){
self.counter(self.counter() + 1);
};
}
var vm = new AppViewModel();
vm.getFakeData(); // replace with getData()
ko.applyBindings(vm);
</script>
小提琴,带有样本数据的getFakeData:https://jsfiddle.net/4hxyarLa/1/
如果你要有很多行并且关注内存,你可以将增量函数放在AppRecord的原型方法中,并通过函数上的参数访问记录,或者你可以将函数添加到AppViewModel并绑定到$ parent.increment来调用它,并通过传递给该函数的参数访问记录,以增加它的计数器属性。