KnockoutJS: Как добавить один наблюдаемый массив в другой? - PullRequest
2 голосов
/ 18 марта 2012

Я хочу добавить выбранные параметры из элемента выбора в таблицу привязок. Модель представления имеет функцию addItem, которая добавляет массив selectedItems в массив addItems с помощью ko.utils.arrayPushAll (). Но ничего не происходит, когда я нажимаю кнопку Добавить (вызывает функцию addItem). Как правильно добавить один наблюдаемый массив в другой?

HTML

<label>Parameter list</label>
<br/>
<select multiple="multiple" 
        data-bind="options: items, selectedOptions: selectedItems, optionsText: 'name', optionsValue: 'id'">
</select>
<p>
    <button data-bind="click: addItem, enable: selectedItems().length > 0">Add</button>
</p>

<label>Selected parameters</label>
<br/>
<table data-bind="visible: addedItems().length > 0">
    <thead>
        <tr>
            <th>Name</th>
            <th>Value</th>
            <th />
        </tr>
    </thead>
    <tbody data-bind="foreach: addedItems">
        <tr>
            <td>
                <input type="hidden" data-bind="value: id"/>
                <span data-bind="text: name" /> 
            </td>
            <td><input type="text" data-bind="value: value" /></td>
            <td><a href="#" data-bind="click: $root.removeItem">Remove</a></td>
        </tr>
    </tbody>
</table>

JavaScript

​var dataSource = [
    new Parameter({ id: "1", name: "param1", value: "" }),
    new Parameter({ id: "2", name: "param2", value: "" }),
    new Parameter({ id: "3", name: "param3", value: "" })
    ];

function Parameter(data) {
    this.id = ko.observable(data.id);
    this.name = ko.observable(data.name);
    this.value = ko.observable(data.value);
}

function ParameterSelectList() {
    // Data
    var self = this;
    self.items = ko.observableArray(dataSource);
    self.selectedItems = ko.observableArray([]);
    self.addedItems = ko.observableArray([]);

    // Operations
    self.addItem = function() {
        ko.utils.arrayPushAll(self.addedItems, self.selectedItems);
        self.items.removeAll(self.selectedItems);
    };
    self.removeItem = function(item) {
        self.items.push(item);
        self.addedItems.remove(item);
    };
}

ko.applyBindings(new ParameterSelectList());​

Пример из жизни - http://jsfiddle.net/6H2PK/7/

ОБНОВЛЕНО : пример работы с удалением выбранных элементов - http://jsfiddle.net/ebash/xxNak/

1 Ответ

4 голосов
/ 18 марта 2012

Здесь происходит несколько вещей:

1) Вы используете привязку 'optionsValue', поэтому selectedItems будет содержать список идентификаторов

2) arrayPushAll работает с «родными» массивами, а не с наблюдаемыми массивами. Вы все еще можете выполнить эту работу, используя формы self.addedItems () и self.selectedItems (), но затем вам нужно будет вызвать self.addedItems.valueHasMutated (), чтобы подписчики знали об изменениях.

3) removeAll принимает "собственный" параметр массива, а не observableArray.

Вот последняя скрипка, которая работает:

http://jsfiddle.net/jearles/6H2PK/8/

...