2013-03-13 2 views
0

То, что я пытаюсь достичь: Форма с одним текстовым полем ввода (Имя), двумя полями выбора с некоторыми параметрами (тип & Столбец) с кнопкой отправки, которая создает виджет с его названием, установленным Name, тип данных, установленным для Type и Column, - это позиция на странице.Передача в наблюдаемом массиве как функциональном параметре

Тип в этом случае имеет несколько различных опций, определенных в представлении, он работает только денди, поэтому я не буду вдаваться в то, как я получил эту работу, пока.

В настоящее время у меня есть страница с тремя колоннами, каждая из которых, как его собственной observableArray - вот так:

self.col0 = ko.observableArray([]); 
self.col0.id = 'col0' 

То же самое касается col1 и col2. Моя цель здесь - получить поле выбора, чтобы указать на эти массивы. По крайней мере, это то, что я думаю, что мне нужно делать.

У меня есть функция createWidget, которая смотрит на значения Name и Type в DOM (исправьте меня, если я ошибаюсь здесь, это самое первое, что я создаю с помощью KnockOut) и создает новый виджет из что данные - например, так:

var Widget = function(name, type) { 
    var self = this; 
    self.name = name; 
    self.type = type; 
}; 

var ViewModel = function() { 
    var self = this; 
    self.newWidgetName = ko.observable(); 
    self.newType  = ko.observable(); 

// Unrelated code in between 

self.createWidget = function(target) { 
    newName = self.newWidgetName(); 
    newType = self.newType(); 
    widget = new Widget(newName, newType); 
    target.unshift(widget) 
    self.newWidgetName(""); 
}; 

Вводные/выберите элементы в DOM

input.widget-name type="text" placeholder="wName" data-bind="value: newWidgetName" 

select data-bind="value: newType" 
    option value="calendar" Calendar 
    option value="article" Article 
    option value="document" Document 

select.colPick data-bind="value: colPick" 
    option value="col0" Column 1 
    option value="col1" Column 2 
    option value="col2" Column 3 

И мой клик обработчик для функции CreateWidget - например, так:

a.btn.create-widget data-bind="click: function(){ createWidget(col0); }" 

Shazam, он работает!

Однако это приведет только к выводу нового виджета в первый col (col0), он не примет значение поля выбора столбца и не переключит новый виджет в правильный столбец. Ошибки я получаю после долгих проб и ошибок, в значительной степени сводится к тому:

1) «Невозможно вызвать метод unshift неопределенных»

2) «Uncaught TypeError: функция объекта наблюдаемым() .... не имеет метода «unshift»

Итак, как сейчас, код выглядит как пример выше, он не идеален каким-либо образом, но с разными столбцами, связанными с сортировкой по нокауту, это не огромная сделка, если эта функциональность пользователь может по-прежнему перемещать виджеты от col0 до col2 и наоборот.

Если у кого есть ресурс, который укажет мне в правильном направлении или ответ на их рукав - не стесняйтесь делиться!

Всего наилучшего, Kas.

Edit: В ответ на вопросы для Tyrsius

С кодом, которую вы предоставили теперь у меня есть три колонки, работающие в поле выбора, но я борюсь немного, когда дело доходит до вывода виджетов в поле зрения.

С моим предыдущим кодом, это то, что вид выглядел как:

<div class="cols"> 
    <div class="col col-25"> 
    <ul data-bind="sortable: { template: 'widgetTmpl', data: col0, afterMove: $root.widgetData }"> 
    </ul> 
    </div> 
    <div class="col col-50"> 
    <ul data-bind="sortable: { template: 'widgetTmpl', data: col1, afterMove: $root.widgetData }"> 
    </ul> 
    </div> 
    <div class="col col-25"> 
    <ul data-bind="sortable: { template: 'widgetTmpl', data: col2, afterMove: $root.widgetData }"> 
    </ul> 
    </div> 
</div> 

Что я работаю сейчас это:

<div data-bind="foreach: columns"> 
    <div data-bind="foreach: items" class="col"> 
    <ul data-bind="sortable: { template: 'widgetTmpl', data: columns, afterMove: $root.widgetData }"></ul> 
    </div> 
</div> 

Мой первый вопрос, я понял, я не был В то время я не думал об этом.

Вопрос №2: Как бы я теперь получил эти Виджеты, связанные с col, которые я выбрал в форме? Буду ли я это делать?

<ul data-bind="sortable: { template: 'widgetTmpl', data: entryColumn, afterMove: $root.widgetData }"></ul> 

Или я в отъезде? :)

ответ

3

Я хотел бы сохранить коллекцию элементов на колонке, как тип, который будет выглядеть следующим образом:

var Column = function(header) { 
    this.header = ko.observable(header); 
    this.items = ko.observableArray([]); 
}; 

Хитрость бы связать столбец select прямо в списке столбцов на ваш ViewModel:

<select data-bind="options: columns, optionsText: 'header', value: entryColumn" 

что происходит здесь является то, что фактический column объект, который выбирается в раскрывающемся списке будут сохранены в entryColumn собственности. Позже мы можем поместить элемент непосредственно в его список items, так как у нас будет ссылка на него. Это также позволяет нам поддерживать любое количество столбцов без изменения логики.

Код добавь будет оставаться простым:

self.columns = ko.observableArray(columns); 

self.entryName = ko.observable(''); 
self.entryType = ko.observable(''); 
self.entryColumn = ko.observable(''); 
self.types = ko.observableArray(['Small', 'Medium', 'Large']); 

self.addWidget = function() { 
     var widget = new Widget(self.entryName(), self.entryType()); 
     //Here is where we can directly add to the selected columns item list 
     self.entryColumn().items.push(widget); 
     self.resetForm(); 
    }; 

Вот the fiddle демонстрирует это.


Followup Вопрос

Вы близки, но данные являются items не EntryColumn

<div data-bind="foreach: columns"> 
    <div data-bind="sortable: { template: 'widgetTmpl', data: items}" class="column">   
    </div> 
</div> 

<script type="text/html" id="widgetTmpl"> 
    <p data-bind="text: name() + ' - ' + type()"></p> 
</script> 

Вот updated fiddle.

+0

Огромное спасибо Тириусу, что сделал! У меня есть несколько следующих вопросов, связанных с циклом foreach и представлением в целом, теперь редактируя главный пост с последующими вопросами. Это, однако, отвечает на вопрос, поэтому я отмечаю его как принятый ответ. Еще раз спасибо! –

+0

@ KasperLewau Смотрите мое обновление – Tyrsius

+0

И вот мы идем! Большое спасибо за вашу помощь, этот надежный очищенный дом в моем коде. Надеюсь, я увижу вас еще немного, как только вы столкнетесь с KnockoutJS! Ура! –