开发者

Call a function on selected index change

How do I bind a function to the selected index change, similar to binding a function to the click event on a button?

The reason I'd need this is that I have this template that has to repeat 'n' number of times. This 'n' is selected from the combobox.

How can I do this using the knockoutJS lib开发者_如何学Gorary as it takes only lists/array objects in its foreach attribute in a template structure?


This could be working for you. The html looks like:

<select id="mySelect">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="4">4</option>
</select>

<table>
    <thead>
        <tr>
            <th></th>
            <th>name</th>
            <th>price</th>
        </tr>
    </thead>
    <tbody data-bind="template: {name:'tempTemplate', foreach:  tempCollection}">
    </tbody>
</table>

and for the javascript:

<script type="text/javascript">
    function temp(name, price ){
        return {name: ko.observable(name),
                price: ko.observable(price)
        };
    }

    $(document).ready(function () {
        var viewModel = {
            tempCollection : ko.observableArray([{ name: "Tall Hat", price: "39.95" }]),
            addTemp: function () { this.tempCollection.push(temp("new","price")) },
            removeTemp: function (temp) { this.tempCollection.remove(temp) }

        };
        ko.applyBindings(viewModel);

        $("#mySelect").change(function() {
            var len = viewModel.tempCollection().length;
            for (var i = 0; i < len; i++) {
                viewModel.removeTemp(viewModel.tempCollection()[0]);
            }
            for (var i = 0; i < $(this).val(); i++) {
                viewModel.addTemp();
            }
        });
});
</script>

<script id="tempTemplate" type="text/html">
    <tr>
        <td><span data-bind="text: name" /></td>
        <td><span data-bind="text: price" /></td>
    </tr>
</script>


The best choice right now is to use a range function that takes a start and stop value and returns an array with those numbers. I, for instance, use the range function in the underscore library.

var numArray = _.range(0, 5); //returns [0, 1, 2, 3, 4]

Use this with knockout like so.

<div data-bind="template: { name: 'myTemplate', foreach: _.range(0, 5) }">
</div>

Inside of the template, you can capture the current number using '$data' and use it like an index.

<div>Index: <span data-bind="text: $data"></span></div>
<div>My Object Prop: <span data-bind="text: viewModel.MyObjects[$data].MyProp"></span></div>

If you want to do a simple iteration as in the previous example, you should iterate over the object directly instead of this array indexing approach. However, if you need to do something fancy, this technique will do the trick.

For instance, if you need to display a list of objects in sets of 2, you could do this.

<div data-bind="foreach: _.range(0, viewModel.MyObjects().length, 2)">
  <div>
    <div data-bind="template: { name: 'myTemplate', data: viewModel.MyObjects()[$data] }"></div>
    <div data-bind="template: { name: 'myTemplate', data: viewModel.MyObjects()[$data + 1] }"></div>
  </div>
</div>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜