【问题标题】:Kendo UI TreeListViews with complex data具有复杂数据的 Kendo UI TreeListViews
【发布时间】:2017-02-16 16:17:33
【问题描述】:

背景信息

简而言之,我希望实现“大部分”这里显示的内容......

http://demos.telerik.com/kendo-ui/treelist/remote-data-binding

...除了它有点让人费解,在我的情况下,数据来自多个基础端点 url。

我正在尝试构建一个通用查询构建页面,该页面允许用户选择一个上下文,然后是一个“类型”(或端点),然后从那里在该端点上构建一个自定义查询。

我已经设法达到了我为简单查询执行此操作的地步,但现在我正在尝试处理更复杂的场景,即从相关端点检索子项或更深的数据项。

考虑到这一点...

概念

我有许多端点,并非所有端点都是 OData,但主要遵循 OData v4 规则,因此我正在尝试构建一个“TreeGrid”,该端点已选择一个端点,该端点将公开可用于查询的扩展选项。 我所有的端点都有一个名为 GetMetadata() 的自定义函数,它描述了该端点的类型信息,其中一个端点基本上是一个 REST CRUD<T> 实现,它可能有也可能没有一些进一步的自定义函数来处理其他一些业务场景。

所以,给定一个 HTTP 获取请求,例如 ...

~/SomeContext/SomeType/GetMetadata()

...我会得到一个看起来很像 MVC / WebAPI 元数据容器的对象。 该对象有一个名为“Properties”的属性,其中一些是标量,一些是复杂的(如数据中所定义)。

我正在尝试构建一个 TreeListDataSource 或 HierarchicalDataSource 对象,我可以使用它来绑定到仅为复杂属性的 Kendo treeList 控件,它动态地为元构建正确的获取 url 并列出该类型的复杂属性基于父类型的属性信息,根端点在页面上的其他控件中定义。

问题

我似乎无法弄清楚如何为 TreeGrid 配置剑道数据源对象以获得所需的输出,我认为可能是以下两个原因之一...

  1. 此处显示的演示中的 TreeListDataSource 对象:http://demos.telerik.com/kendo-ui/treelist/local-data-binding 似乎暗示基于层次结构的控件需要平面数据源。
  2. 我不知道如何配置数据源,以便我可以传入父元信息(来自源的数据项)以便为 get 请求构建正确的端点 url。
function getDatasource(rootEndpoint) {
    return {
        pageSize: 100,
        filter: { logic: 'and', filters: [{ /* TODO:possibly filter properties in here? */ }] },
        type: 'json',
        transport: {
            read: {
                url: function (data) {
                    //TODO: figure out how to set this based on parent
                    var result = my.api.rootUrl + endpoint + "/GetMetadata()";
                    return result;
                },
                dataType: 'json',
                beforeSend: my.api.beforeSend
            }
        },

        schema: {
            model: {
                id: 'Name',
                fields: {
                    Type: { field: 'Type', type: 'string' },
                    Template: { field: 'Template', type: 'string' },
                    DisplayName: { field: 'DisplayName', type: 'string' },
                    ShortDisplayName: { field: 'ShortDisplayName', type: 'string' },
                    Description: { field: 'Description', type: 'string' },
                    ServerType: { field: 'ServerType', type: 'string' }
                }
            }
            parse: function (data) {
                // the object "data" passed in here will be a meta container, a single object that contains a property array.
                $.each(data.Properties, function (idx, item) {
                    item.ParentType = data;
                    item.Parent = ??? where do I get this ???
                });

                return data.Properties;
            }
        }
    };
}

我的一些问题可能归结于元数据本身没有主键这一事实,我想知道是否使用 parse 附加生成的 guid 作为键可能是一个想法,但后来我认为 Kendo 使用了 id询问孩子时关于API的问题。

【问题讨论】:

    标签: javascript kendo-ui telerik kendo-treeview


    【解决方案1】:

    所以事实证明,剑道除了从单个端点提供数据外,还没有准备好做任何事情,而我在这里做的事情比这要复杂一些,而且更多是由于数据是“非实体类型数据”我没有键和外键等常见的东西。

    考虑到这一点,我选择将问题完全从剑道中移开,并简单地通过一些“行为类似于普通剑道扩展但不是真正的黑客”来处理这种情况......

    在树形网格中,当剑道显示可展开的行时,它会在第一个单元格中呈现类似这样的内容...

    如果没有扩展数据或绑定到服务器的数据源,则不会呈现此单元格。

    所以我在原地伪造了它,并在我的版本中添加了一个额外的类 .not-loaded。

    这意味着我可以在单击“假扩展”时连接一个自定义的 js 块,以构建正确的 url,做我的自定义内容,伪造/创建一些 id,然后将数据交给数据源。

    expandList.on('click', '.k-i-expand.not-loaded', function (e) {
        var source = expandList.data("kendoTreeList");
        var cell = $(e.currentTarget).closest('td');
        var selectedItem = source.dataItem($(e.currentTarget).closest('tr'));
        my.type.get(selectedItem.ServerType, ctxList.val(), function (meta) {
            var newData = JSLINQ(meta.Properties)
                .Select(function (i) {
                    i.id = selectedItem.id + "/" + i.Name;
                    i.parentId = selectedItem.id;
                    i.Selected = my.type.ofProperty.isScalar(i);
                    i.TemplateSource = buildDefaultTemplateSourceFor(i);
                    return i;
                })
                .ToArray();
    
            for (var i in newData) {
                source.dataSource.add(newData[i]);
            }
    
            $(e.currentTarget).remove();
            source.expand(selectedItem);
            buildFilterGrid();
            generate();
        });
    });
    

    通过这种方式,剑道得到了树视图列表“具有父子关系的平面集”的预期,而我完成了所有繁重的工作。

    我使用了一点 JSLINQ 魔法让繁重的工作更像“c#”(毕竟我更喜欢 c#),但总之它所做的只是抓取扩展的父项并使用来自作为父级然后为当前项目生成一个新的id作为parent.id +“/”+ current.name,这样一切都是唯一的,因为一个对象上的2个属性不能具有相同的名称,并且两个对象在哪里由同一父级引用,父级属性名称的前缀使引用唯一。

    这不是理想的解决方案,但这就是 Telerik 的运作方式,这里有一个 hack,那里有一个 hack,通常可以让它工作!

    但有些事情告诉我有一个更聪明的方法可以做到这一点!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-17
      • 1970-01-01
      • 2012-09-17
      相关资源
      最近更新 更多