单击同一行中的按钮后减少一个值 - 淘汰赛

时间:2016-01-23 19:25:30

标签: javascript knockout.js

我有一张桌子,我填写了一些数字。每行都有一个按钮。单击此按钮后,我想在此行中减少一个计数器。怎么用淘汰赛这个?

<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>

2 个答案:

答案 0 :(得分:1)

我会这样做:

  1. 从服务器获取的流程数据,将counter属性转换为observable并添加函数以减少计数器属性
  2. 重新编码您的代码,以便在ajax请求时创建viewmodel
  3. applyBindings调用移至ajax回调,以便在加载所有内容时触发
  4. 所以代码看起来像:

        <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来调用它,并通过传递给该函数的参数访问记录,以增加它的计数器属性。