Вызов функции при изменении выбранного индекса

Как привязать функцию к выбранному изменению индекса, аналогично привязке функции к событию нажатия на кнопку?

Причина, по которой мне это нужно, заключается в том, что у меня есть этот шаблон, который должен повторяться «n» раз. Это «n» выбирается из выпадающего списка.

Как я могу сделать это, используя библиотеку KnockoutJS, поскольку она принимает только объекты списков/массивов в своем атрибуте foreach в структуре шаблона?


person Naveen Velaga    schedule 25.08.2011    source источник
comment
Не уверен насчет Knockout.js, но событие изменения поля со списком должно быть $('.selector').change(function() {...});. Чтобы получить выбранное значение, просто выполните $('.selector').val();. Если это в основном то, что вы ищете, я могу отправить более подробный ответ... надеюсь, это поможет.   -  person jyore    schedule 25.08.2011


Ответы (2)


Это может работать на вас. HTML выглядит так:

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

и для 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>
person Major Byte    schedule 26.08.2011
comment
Спасибо.. это то, что мне нужно :) - person Naveen Velaga; 26.08.2011
comment
тогда, если бы вы могли принять ответ, stackoverflow.com/faq#howtoask Но я рад, что смог вам помочь. - person Major Byte; 26.08.2011

На данный момент лучший выбор — использовать функцию диапазона, которая принимает начальное и конечное значения и возвращает массив с этими числами. Я, например, использую функцию диапазона в библиотеке underscore.

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

Используйте это с нокаутом вот так.

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

Внутри шаблона вы можете зафиксировать текущий номер с помощью «$ data» и использовать его как индекс.

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

Если вы хотите выполнить простую итерацию, как в предыдущем примере, вам следует выполнять итерацию непосредственно по объекту вместо этого подхода с индексацией массива. Однако, если вам нужно сделать что-то необычное, эта техника поможет.

Например, если вам нужно отобразить список объектов в наборах по 2, вы можете сделать это.

<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>
person Malgaur    schedule 20.04.2012