Как привязать DropDownList к источнику данных в шаблоне редактора с помощью планировщика?

Я пытаюсь настроить использование виджета Kendo UI kendoScheduler. Я указываю пользовательский шаблон для редактируемого окна, которое появляется, когда вы добавляете/редактируете встречу в планировщике, например так:

editable: {
                template: $("#editor").html()
            },

Я определяю шаблон следующим образом:

<script id="editor" type="text/x-kendo-template">
<h3>Edit Appointment</h3>
   <p>
       <label>Patient: <input name="title" /></label>
   </p>
   <p>
       <label>Start: <input data-role="datetimepicker" name="start" /></label>
   </p>
</script>

Итак, теперь я хочу добавить Kendo UI DropDownList и настроить его для заполнения из удаленного источника данных. Как вы настраиваете такие вещи в шаблоне?

Пример кода (не работает):

<p>
    <label>Type: </label><input id="appointmentTypeDropDownList" />
</p>
# var dataSource = new kendo.data.DataSource({ transport: { read: { url: "http://demos.kendoui.com/service/products", dataType: "jsonp" } } });
# $("#appointmentTypeDropDownList").kendoDropDownList({ dataSource: dataSource, dataTextField: "ProductName", dataValueField: "ProductID" } ) ;

Ошибка, которую он дает с приведенным выше кодом: Uncaught Error: Invalid template:'

Вероятно, это просто проблема с кодировкой скрипта; Меня больше интересует правильный способ размещения связанного DropDownList внутри шаблона.

Обновление. Последняя упрощенная версия того, что я пытаюсь сделать, доступна по этому URL jsfiddle. Цель состоит в том, чтобы просто связать выпадающий список самым простым способом. Спасибо!


person ssmith    schedule 25.01.2014    source источник


Ответы (3)


Если вы переместите свой источник данных планировщика в свой viewModel, вы можете использовать родительские функции наблюдаемого кендо, чтобы привязать DropDownList к правильному источнику данных.

var viewModel = new kendo.observable({
    appointmentTypes : new kendo.data.DataSource({
        data: [{
            id: 1,
            text: "Wellness Exam"
        }, {
            id: 2,
            text: "Diagnostic Exam"
        }, {
            id: 3,
            text: "Nail Trim"
        }]
    }),
    schedulerData: [{
        id: 1,
        start: new Date("2014/1/27 08:00 AM"),
        end: new Date("2014/1/27 09:00 AM"),
        title: "Breakfast"
    }]
});

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

$("#scheduler").kendoScheduler({
    ...
    dataSource: viewModel.schedulerData,
    ...
});

Последняя часть просто изменяет ваше объявление DropDownList, чтобы использовать свойство appointmentTypes в вашей модели представления.

<select id="appointmentTypeDropDownList" data-bind="source:appointmentTypes, value:id" data-text-field="text" data-value-field="id" data-role="dropdownlist" data-autobind="true" />

Поскольку ваш шаблон будет привязан к объектам Observable в schedulerData DataSource, Kendo будет подниматься по родительскому дереву объекта, пока не сможет разрешить свойство appointmentTypes, которое находится в viewModel.

person Thomas Mullaly    schedule 30.01.2014
comment
И это задокументировано где? Спасибо! - person ssmith; 30.01.2014
comment
Я тоже был очень удивлен, что это сработало. Большое спасибо, но есть ли ссылка, где задокументированы функции родительского контроля? - person Sasha; 30.07.2015

Шаблон выдает ошибку, поскольку селектор "#appointmentTypeDropDownList" должен быть экранирован и выглядеть следующим образом: "\\#appointmentTypeDropDownList" (Документация по пользовательскому интерфейсу кендо).

После того, как вы это исправите, вы не будете получать ошибки шаблона, но он по-прежнему не привязывает данные к KendoDropDownList. Я проверил, что в этом случае будет отображать помощник KendoUI MVC, и кажется, что если ваш шаблон выглядит так, он будет работать.

<script id="editor" type="text/x-kendo-template">
       <h3>Edit meeting</h3>
       <p>
           <label>Title: <input name="title" /></label>
       </p>
       <p>
           <label>Start: <input data-role="datetimepicker" name="start" /></label>
       </p>
       <p>
           <label>Start: <input data-role="datetimepicker" name="end" /></label>
       </p>

        <p>
            <label>Type: </label><input id="appointmentTypeDropDownList" />

                <script>
                    var dataSource = new kendo.data.DataSource({ transport: { read: { url: "http://demos.kendoui.com/service/products", dataType: "jsonp" } } }); 

                    jQuery(function() { jQuery("\\#appointmentTypeDropDownList").kendoDropDownList({ dataSource: dataSource, dataTextField: "ProductName", dataValueField: "ProductID" } ); });
                 <\/script>
        </p></script>
person Tosho Toshev    schedule 26.01.2014
comment
Нужны интересные вложенные блоки скриптов. Я все еще не уверен, что это правильный способ сделать это, в отличие от простой передачи статических данных в шаблон для рендеринга, который заполняется извне шаблона. Я предполагаю, что это то, что я должен делать, и в этом случае будет хорошо, если я смогу перехватить любое событие, которое выдает планировщик, до того, как он покажет окно редактора (поскольку данные будут зависеть от выбранной даты и времени). - person ssmith; 26.01.2014

Нет необходимости помещать какой-либо javascript в шаблон, вы можете использовать функции инициализации атрибутов данных Kendo.

Итак, ваш шаблон будет выглядеть примерно так:

<label>Type: </label>
<input id="appointmentTypeDropDownList" data-text-field="ProductName" data-value-field="ProductID" data-bind="value:ProductID" data-source="dataSource" data-role="dropdownlist" data-autobind="true" />

Тогда у вас будет Javascript за пределами вашего шаблона:

var dataSource = new kendo.data.DataSource({
  transport: { 
    read: { 
      url: "http://demos.kendoui.com/service/products", 
      dataType: "jsonp"
    }
  }
});

Пока dataSource определено глобально, все в порядке. Дополнительную информацию об инициализации атрибутов данных можно найти здесь http://docs.telerik.com/kendo-ui/getting-started/data-attribute-initialization

Изменить: только что заметил ваш комментарий «данные будут зависеть от выбранной даты и времени». Вы всегда можете попробовать переопределить параметры источника данных в событии edit, которое вызывается перед отображением всплывающего окна редактора. Я не использовал этот сценарий, но не понимаю, почему он не сработает.

person Mat    schedule 27.01.2014
comment
Спасибо, этот подход работает только в том случае, если я использую MVVM и модель представления? Мне не удалось заставить его работать в моем коде, но мне удалось заставить этот jsFiddle работать после того, как я решил включить модель представления: jsfiddle.net/vNSX4 - person ssmith; 29.01.2014
comment
Ну, я использую описанный подход без MVVM и viewModel, и он отлично работает. Я посмотрю, смогу ли я найти время, чтобы поставить скрипку (но запросы ajax делают это немного сложнее). В качестве альтернативы, если вам интересно, я могу просто разместить код в том виде, в котором он есть (он не будет работать), чтобы вы могли увидеть, как все это настроено. - person Mat; 30.01.2014