具有复杂数据的Kendo UI TreeListViews

时间:2017-02-16 16:17:34

标签: javascript kendo-ui telerik kendo-treeview

背景资料

简而言之,我希望实现"主要是"这里显示的是什么......

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

...除了它有点令人费解,在我的情况下数据来自多个基本端点网址。

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

我已经设法达到一个简单查询的目的,但现在我正在尝试处理更复杂的场景,我从相关端点检索子项或更深层次的数据项。

考虑到这一点......

概念

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

所以,给定一个HTTP get请求......

~/SomeContext/SomeType/GetMetadata()

...我会找回一个看起来很像MVC / WebAPI元数据容器的对象。 该对象有一个名为&#34; Properties&#34;其中一些是标量的,其中一些是复杂的(如数据中所定义)。

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

问题

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

  1. 根据此处显示的演示,TreeListDataSource对象:http://demos.telerik.com/kendo-ui/treelist/local-data-binding似乎暗示基于层次结构的控件需要平面数据源。
  2. 我无法弄清楚如何配置数据源,以便我可以传递父元信息(来自源的数据项),以便为get请求构建正确的端点URL。 / LI>
    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;
                }
            }
        };
    }
    

    我的一些问题可能归结为元数据本身并不具有主键这一事实,我想知道是否可能使用解析来附加生成的guid,因为关键可能是一个想法,但我认为Kendo使用在询问孩子时,API问题的ID。

1 个答案:

答案 0 :(得分:0)

所以事实证明,剑道只是不做任何事情而不是提供来自单个端点的数据,我在这里做的事情比这更复杂,而且更多是由于数据是“非实体类型数据”我没有常见的东西,如键和外键。

考虑到这一点,我选择将问题完全从剑道中解决出来并简单地处理这种情况,其中一些“黑客表现得像普通的剑道扩展而不是真的”...

在treegrid中,当kendo显示可扩展的行时,它会在第一个单元格中呈现类似的内容...

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

所以我把它假装到位并为我的版本添加了一个额外的类.not-loaded。

这意味着我可以点击我的“假扩展”来连接自定义js块,构建正确的URL,执行我自定义的东西,伪造/创建一些id,然后将数据传递给数据源。 / p>

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#like”(我更喜欢c#),但简而言之,它只是抓住扩展的父项并使用来自然后,当父级生成当前项的新id作为parent.id +“/”+ current.name时,这样一切都是唯一的,因为对象上的2个属性不能具有相同的名称,并且其中两个对象是由同一父级引用的父属性名称的前缀使引用唯一。

这不是理想的解决方案,但这就是telerik的事情,这里的黑客攻击,黑客攻击,通常可以让它工作!

有些东西告诉我,虽然有更聪明的方法!