在 Knockout JS 中为每个循环过滤 Kendo UI ComboBox
Filtered KendoUI ComboBox in KnockoutJS foreach cycle
我正在尝试创建显示初始数据的可编辑表单,当用户进入编辑模式时,Kendo 组合框显示为 select 个新值。
只有当用户启动编辑模式时,组合框的所有值才会按需加载(不需要为客户端获取数据只是为了查看当前状态)。
换句话说 - 表单显示为只读输入。单击 "edit" 按钮。这将调用服务来加载数据(不在 fiddle 中,只是辅助方法)并在 foreach 循环中显示按每个项目的特定 ID 过滤的组合框。因此每个 ComboBox 仅显示基于过滤器的适当值。
如何创建 GetBrokersInRole() 的工作版本并将其绑定到表单数据?
谢谢
标记:
<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>
视图模型:
// 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());
我看到有两件事可以帮助解决这个问题。首先,Knockout-Kendo 未设置为跟踪对不可观察或计算的事物的依赖性(例如 returns 值的函数)。所以,它没有重新评估。
您可以在每个 Roles
上创建一个计算来表示该数据,或者根据您的代码,您可以像这样包装 kendoComboBox
:
<!-- ko with: $root.GetBrokersInRole($data) -->
<input data-bind="kendoComboBox: { data: $data, dataTextField: 'BrokerName', dataValueField: 'BrokerID', value: $parent.ValueID }" />
<!-- /ko -->
现在,当 GetBrokersInRole
中访问的依赖项更新时,它将正确地重新呈现。
此外,您的过滤逻辑看起来有点不对劲(至少对于 fiddle 中的代码而言)。您角色的属性不可观察,也没有 RoleTypeID
。或许是这样:
var filtered = ko.utils.arrayFilter(self.BrokersInRoles(), function (broker) {
return _.contains(broker.RolesID.split(';'), roleItem.RoleID.toString());
});
已更新 fiddle:http://jsfiddle.net/rniemeyer/kz5o5h5y/
我正在尝试创建显示初始数据的可编辑表单,当用户进入编辑模式时,Kendo 组合框显示为 select 个新值。
只有当用户启动编辑模式时,组合框的所有值才会按需加载(不需要为客户端获取数据只是为了查看当前状态)。
换句话说 - 表单显示为只读输入。单击 "edit" 按钮。这将调用服务来加载数据(不在 fiddle 中,只是辅助方法)并在 foreach 循环中显示按每个项目的特定 ID 过滤的组合框。因此每个 ComboBox 仅显示基于过滤器的适当值。
如何创建 GetBrokersInRole() 的工作版本并将其绑定到表单数据?
谢谢
标记:
<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>
视图模型:
// 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());
我看到有两件事可以帮助解决这个问题。首先,Knockout-Kendo 未设置为跟踪对不可观察或计算的事物的依赖性(例如 returns 值的函数)。所以,它没有重新评估。
您可以在每个 Roles
上创建一个计算来表示该数据,或者根据您的代码,您可以像这样包装 kendoComboBox
:
<!-- ko with: $root.GetBrokersInRole($data) -->
<input data-bind="kendoComboBox: { data: $data, dataTextField: 'BrokerName', dataValueField: 'BrokerID', value: $parent.ValueID }" />
<!-- /ko -->
现在,当 GetBrokersInRole
中访问的依赖项更新时,它将正确地重新呈现。
此外,您的过滤逻辑看起来有点不对劲(至少对于 fiddle 中的代码而言)。您角色的属性不可观察,也没有 RoleTypeID
。或许是这样:
var filtered = ko.utils.arrayFilter(self.BrokersInRoles(), function (broker) {
return _.contains(broker.RolesID.split(';'), roleItem.RoleID.toString());
});
已更新 fiddle:http://jsfiddle.net/rniemeyer/kz5o5h5y/