2015-04-08 6 views
1

Я пытаюсь создать редактируемую форму, где отображаются исходные данные, и когда пользователь переходит в режим редактирования, Kendo ComboBoxes отображаются для выбора новых значений.Отфильтрованный KendoUI ComboBox в KnockoutJS foreach cycle

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

Иными словами - форма отображается как прочитанная только с входами. Нажмите кнопку «Изменить». Это вызовет услугу для загрузки данных (не в скрипте, только вспомогательный метод) и отображает ComboBox, отфильтрованные по конкретному идентификатору для каждого элемента цикла foreach. Поэтому каждый ComboBox отображает только правильные значения на основе фильтра.

Как создать рабочую версию GetBrokersInRole() и связать ее с данными?

Thnx

Markup:

<div data-bind="foreach: Roles"> 
    <label data-bind="text: RoleName"></label> 
    <div data-bind="visible: !$root.IsEditMode()"> 
     <input data-bind="enable: $root.IsEditMode(), value: ValueText" /> 
    </div> 
    <div data-bind="visible: $root.IsEditMode()"> 
     <!-- OK --> 
     <input data-bind="kendoComboBox: { data: $root.BrokersInRoles, dataTextField: 'BrokerName', dataValueField: 'BrokerID', value: ValueID }" /> 
     <!-- NOT OK --> 
     <input data-bind="kendoComboBox: { data: $root.GetBrokersInRole($data), dataTextField: 'BrokerName', dataValueField: 'BrokerID', value: ValueID }" /> 
    </div> 
</div> 
<p> 
    <button data-bind="click: StartEdit">Set Edit Mode</button> 
</p> 
<label data-bind="text: Brokers().length"></label> 

ViewModel:

// Roles and initial values 
var roles = [ 
    {"RoleID":1,"RoleName":"Role 1","ValueID":101,"ValueText":"Broker 1"}, 
    {"RoleID":2,"RoleName":"Role 2","ValueID":102,"ValueText":"Broker 2"}, 
    {"RoleID":3,"RoleName":"Role 3","ValueID":103,"ValueText":"Broker 3"}, 
    {"RoleID":4,"RoleName":"Role 4","ValueID":104,"ValueText":"Broker 4"} 
]; 

// RolesID is collection of Roles where Broker is available 
// so BrokerID=101 is available in ComboBox for RoleID 1 and 3 
var brokers = [ 
    {"BrokerID":101,"BrokerName":"Broker 1","RolesID":"1;3"}, 
    {"BrokerID":102,"BrokerName":"Broker 2","RolesID":"1;2"}, 
    {"BrokerID":103,"BrokerName":"Broker 3","RolesID":"3"}, 
    {"BrokerID":104,"BrokerName":"Broker 4","RolesID":"4"} 
]; 

// ViewModel 
var ViewModel = function() { 

    // Roles and initial values 
    this.Roles = ko.observableArray(roles); 
    // Initial value is empty - no comboboxes if not in edit mode (save data) 
    this.BrokersInRoles = ko.observableArray([]); 
    // Is edit mode? 
    this.IsEditMode = ko.observable(false); 

    // Alternative method to AJAX load of Brokers collection 
    // Until edit mode is active, BrokersInRoles collection is empty 
    this.StartEdit = function() 
    { 
     var self = this; 
     self.BrokersInRoles(brokers); // This will be AJAX load on demand 
     self.IsEditMode(true); 
    }; 

    // Filter brokers based on role 
    this.GetBrokersInRole = function (roleItem) { 
     var self = this; 

     var filtered = ko.utils.arrayFilter(self.BrokersInRoles(), function (broker) { 
      return _.contains(broker.RolesID().split(';'), roleItem.RoleTypeID().toString()); 
     }); 

     // Return only brokers in selected role 
     return ko.observableArray(filtered); 
    }; 
}; 

ko.applyBindings(new ViewModel()); 

Fiddle: http://jsfiddle.net/RaptorCZ/drkb6mLk/

ответ

0

Я вижу две вещи, которые могут помочь исправить это. Во-первых, Knockout-Kendo не настроен для отслеживания зависимостей от того, что не является наблюдаемым или вычисленным (например, функция, возвращающая значения). Таким образом, он не переоценивается.

Вы можете создать вычислен на каждом из вашего Roles, чтобы представить эти данные или на основе кода, можно обернуть kendoComboBox как:

<!-- ko with: $root.GetBrokersInRole($data) --> 
    <input data-bind="kendoComboBox: { data: $data, dataTextField: 'BrokerName', dataValueField: 'BrokerID', value: $parent.ValueID }" /> 
    <!-- /ko --> 

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

Кроме того, похоже, что ваша логика фильтрации немного выключена (по крайней мере, для кода в вашей скрипке). Свойства на ваших ролях не наблюдаются, и не было RoleTypeID. Возможно, это:

var filtered = ko.utils.arrayFilter(self.BrokersInRoles(), function (broker) { 
     return _.contains(broker.RolesID.split(';'), roleItem.RoleID.toString()); 
}); 

Обновлено скрипку: http://jsfiddle.net/rniemeyer/kz5o5h5y/

+0

Удивительно, Thnx за помощью. Да, функция фильтрации немного сломана, из-за копирования и вставки из реального проекта, чтобы упростить задачу. – Raptor

Смежные вопросы