2016-05-17 99 views
0

可能会涉及这种错误的方式,但我有一个使用foreach使用knockout可观察数组填充的html表。在每一行我有一个下拉。我喜欢jquery ui选择菜单,所以我正在使用它。不幸的是,当您运行小提琴时,您会注意到,在更新下拉菜单时,相应的淘汰赛选定值未被更新。同步jquery ui选择菜单与淘汰赛可观察阵列

这里是小提琴https://jsfiddle.net/8rw4ruze/3/ 这里是html。

<table class="table table-condensed table-responsive"> 
    <thead> 
    <th>id</th> 
    <th>animal</th> 
    <th>Selected Value</th> 
    </thead> 
    <tbody data-bind="foreach: tableRows"> 
    <tr> 
     <td data-bind="text: id"></td> 
     <td> 
     <select class="form-control" data-bind="options: recordList, 
        optionsText: 'desc', 
        optionsValue: 'val', 
        value: selectedVal, 
        attr: {id: selectId}"> 

     </select> 
     </td> 
     <td data-bind="text: selectedVal"></td> 
    </tr> 
    </tbody> 
</table> 

这里是JavaScript

function record(val, desc) { 
    var self = this; 
    this.val = ko.observable(val); 
    this.desc = ko.observable(desc); 
} 

function tableRow(id, recordList) { 
    var self = this; 
    this.id = ko.observable(id); 
    this.recordList = ko.observable(recordList) 
    this.selectedVal = ko.observable('A'); 
    this.selectId = ko.computed(function() { 
    return 'mySelect' + self.id() 
    }, this); 
} 

function Model() { 
    var self = this; 
    this.records = ko.observableArray(""); 
    this.tableRows = ko.observableArray(""); 
} 

var mymodel = new Model(); 

$(function() { 

    mymodel.records.push(new record('A', 'ant')); 
    mymodel.records.push(new record('B', 'bird')); 
    mymodel.records.push(new record('C', 'cat')); 
    mymodel.records.push(new record('D', 'dog')); 
    mymodel.tableRows.push(new tableRow(1, mymodel.records())); 
    mymodel.tableRows.push(new tableRow(2, mymodel.records())); 
    mymodel.tableRows.push(new tableRow(3, mymodel.records())); 
    mymodel.tableRows.push(new tableRow(4, mymodel.records())); 


    ko.applyBindings(mymodel); 

    for (var i = 0; i < 4; i++) { 
    var id = '#mySelect' + (i + 1) 
    $(id).selectmenu({ 
     width: 125, 
     change: function(event, ui) { 
     var newVal = $(this).val(); 
     mymodel.tableRows()[i].selectedVal(newVal); 
     } 
    }); 
    } 


}); 

感谢所有我与数据属性去。我更喜欢使用自定义绑定,但我不够聪明来弄清楚,所以我就这样做了。

for (var i = 0; i < 4; i++) { 
    var id = '#mySelect' + (i + 1) 
    $(id).selectmenu({ 
     width: 125, 
     change: function(event, ui) { 
     var newVal = $(this).val(); 
     var index = $(this).data("index"); 
     mymodel.tableRows()[index].selectedVal(newVal); 
     } 
    }).data("index", i); 
    } 

这里是小提琴https://jsfiddle.net/8rw4ruze/7/

我觉得我得到了它与自定义绑定这里是 https://jsfiddle.net/8rw4ruze/8/

+1

'mymodel.tableRows()[i]'是'undefined',因为在加载页面后i已经是4了。 –

+0

所以我应该为每个选择(1,2,3,4)添加一个数据属性,然后在on change事件中引用select的数据属性? –

+0

如果我是你,我会使用'knockout'内置'dropDown',你可以订阅selectedVal。例如:https://jsfiddle.net/8rw4ruze/5/ –

回答

0

Matt.k工作是正确的,你我的价值是不是你想要的它被使用时。周围的一种方法是使用这种循环,而不是一个简单的for

$('select').each(function (i, e) { 
    e.selectmenu({ 
    width: 125, 
    change: function(event, ui) { 
     var newVal = $(this).val(); 
     mymodel.tableRows()[i].selectedVal(newVal); 
    } 
    }); 
}); 

这是有点脆弱,因为它依赖于ie正确对应。更强大的Knockout方法是使用绑定处理程序,它允许您指定绑定并使Knockout遍历元素并进行必要的调用。令人惊讶的是,一点网络搜索没有为我提供帮助。

我看到有一个knockout-jqueryui project on github,也可能会给你一个干净的方式使用你想要的部件。

+0

感谢您的建议,我会尝试实现一个绑定处理程序,我从来没有这样做过。然而在此期间,我使用了一个数据属性(我更新了我的原始文章) –

+0

嘿,我想我在这里使用了自定义绑定,它是https://jsfiddle.net/8rw4ruze/8/ –