【问题标题】:Filtered KendoUI ComboBox in KnockoutJS foreach cycle在 Knockout JS foreach 循环中过滤 Kendo UI ComboBox
【发布时间】:2015-04-08 13:18:53
【问题描述】:

我正在尝试创建显示初始数据的可编辑表单,当用户进入编辑模式时,会显示 Kendo ComboBoxes 以选择新值。

只有当用户启动编辑模式时,组合框的所有值才会按需加载(无需为了查看当前状态而将数据提取到客户端)。

换句话说 - 表单显示为只读输入。点击“编辑”按钮。这将调用服务来加载数据(不是在小提琴中,只是辅助方法)并显示按特定 ID 过滤的组合框,用于 foreach 循环中的每个项目。所以每个 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());

小提琴: http://jsfiddle.net/RaptorCZ/drkb6mLk/

【问题讨论】:

    标签: knockout.js kendo-ui kendo-combobox


    【解决方案1】:

    我发现有两件事可以帮助解决这个问题。首先,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/

    【讨论】:

    • 太棒了,谢谢帮助。是的,过滤功能很少损坏,因为从实际项目中复制和粘贴以简化问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 2014-02-13
    • 2018-05-07
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多