extjs 深入搜索商店数据?

Posted

技术标签:

【中文标题】extjs 深入搜索商店数据?【英文标题】:extjs searching deep into store data? 【发布时间】:2012-09-16 05:23:27 【问题描述】:

在 Flex 应用程序中,元数据被加载为 xml,它具有很好的功能,可以深入搜索 xml 节点。在 extjs 版本中,我已将 xml 数据转换为 json,保留深层分层内容,并使用 json 阅读器加载到 extjs Store。我没有创建模型,认为这没有必要,因为模型没有添加任何搜索功能(?)。我正在查看可以使用函数的 store.find、store.findBy、store.findRecord 等,但这些函数看起来非常“单一”。我需要转到“Tabs”“节点”,找到其“名称”为“Tab1”的子“Tab”,并找到其属性“Title”的值......我正在使用描述“节点”但它是分层的 json 数据。我是否缺少可以执行此操作的商店功能,我应该使用商店的原始 json 数据 - json 是否具有更好的搜索功能,或者我是否应该通过循环遍历所有“节点”来恢复暴力 javascript?我希望避免循环并找到某种功能。和往常一样,tia

【问题讨论】:

你能发布一个你的json的例子吗? json 实际上可以是任何格式,因为我将它创建为元数据来定义应用程序本身。它是非常分层的,例如如上所述,TabBar 有多个带有属性的选项卡,每个选项卡都有带有属性的网格等。我想知道是否应该将其格式化以加载到 TreeStore 中,这似乎具有更多“深入了解”的功能?跨度> 我认为问题不在于商店的类型:也许,您需要模型关联来管理嵌套的 json 数据。 我想知道,但模型似乎更像是传统的“从后端加载业务数据,允许用户修改它,保存到后端”等的一部分?由于这是应用程序功能内部的元数据,因此我需要一种在需要时获取正确“节点”的有效方法。 【参考方案1】:

嗯,我从我们的 cmets 了解到,您需要一种存储来尽可能快速轻松地访问您的 JSON 数据。 JSON 表示 JavaScript Object Notation,所以它是一个对象!

好的,我给你举两个例子。 首先,设置 JSON 数据:


    "users": [
        "user": 
            "id": 0 ,
            "name": "foo" ,
            "age": 22 ,
            "skills": [
                "type": "bowcrafting" ,
                "skillLevel": 50 ,
                "levels": [10, 25, 50, 75, 90, 95, 99, 100]
            ]
         ,  
        "user": 
            "id": 1 ,
            "name": "bar" ,
            "age": 71 ,
            "skills": [
                "type": "fencing" ,
                "skillLevel": 32 ,
                "levels": [10, 25, 50, 90, 95, 99, 100]
             , 
                "type": "swordsmanship" ,
                "skillLevel": 73 ,
                "levels": [10, 25, 50, 75, 80, 85, 90, 95, 99, 100]
            ]
         , 
        "user": 
            "id": 2 ,
            "name": "foobar" ,
            "age": 132 ,
            "skills": [
                "type": "tactics" ,
                "skillLevel": 90 ,
                "levels": [10, 25, 50, 90, 95, 99, 100]
             , 
                "type": "carpentery" ,
                "skillLevel": 86 ,
                "levels": [10, 25, 50, 75, 90, 95, 99, 100]
             , 
                "type": "hiding" ,
                "skillLevel": 100 ,
                "levels": [10, 25, 50, 65, 75, 80, 85, 90, 95, 99, 100]
            ]
        
    ]

现在我们有两种方法可以遵循:

第一种方式:我们可以想象将上面的 JSON 保存到一个名为 nested-json.json 的文件中,然后我们通过一个简单的存储来读取它。然后,我们可以使用 findBy 搜索来找到我们需要的东西:

var jstore = Ext.create ('Ext.data.Store', 
    fields: ['id', 'name', 'age', 'skills'] ,

    proxy: 
        type: 'ajax' ,
        url: 'nested-json.json' ,
        reader: 
            type: 'json' ,
            root: 'users' ,
            record: 'user' ,
            idProperty: 'id'
        
     ,

    autoLoad: true
);

Ext.create ('Ext.button.Button', 
    text: 'Push me' ,
    renderTo: Ext.getBody () ,
    handler: function (btn) 
        var index = jstore.findBy (function (user, id) 
            // Here's the hint
            if (user.data.skills.skillLevel === 50) return id;
            else return -1;
        );

        if (index != -1) 
            // It will print 'foo' because it's the user
            // that has the skillLevel equal to 50
            console.log (jstore.getAt(index).get ('name'));
        
    
);

另一种方法是将上面的 JSON 想象成一个对象,直接从原始 JSON 数据中读取。此时,只需将其用作 javascript 对象即可:

// Users model: required by JSON reader
Ext.define ('Users', 
    extend: 'Ext.data.Model' ,
    fields: ['id', 'name', 'age', 'skills']
);

// JSON reader
var jreader = Ext.create ('Ext.data.reader.Json', 
    model: 'Users' ,
    root: 'users' ,
    record: 'user' ,
    idProperty: 'id'
);

// Reads records directly from raw JSON
var users = jreader.readRecords (
    "users": [
        "user": 
            "id": 0 ,
            "name": "foo" ,
            "age": 22 ,
            "skills": [
                "type": "bowcrafting" ,
                "skillLevel": 50 ,
                "levels": [10, 25, 50, 75, 90, 95, 99, 100]
            ]
         ,  
        "user": 
            "id": 1 ,
            "name": "bar" ,
            "age": 71 ,
            "skills": [
                "type": "fencing" ,
                "skillLevel": 32 ,
                "levels": [10, 25, 50, 90, 95, 99, 100]
             , 
                "type": "swordsmanship" ,
                "skillLevel": 73 ,
                "levels": [10, 25, 50, 75, 80, 85, 90, 95, 99, 100]
            ]
         , 
        "user": 
            "id": 2 ,
            "name": "foobar" ,
            "age": 132 ,
            "skills": [
                "type": "tactics" ,
                "skillLevel": 90 ,
                "levels": [10, 25, 50, 90, 95, 99, 100]
             , 
                "type": "carpentery" ,
                "skillLevel": 86 ,
                "levels": [10, 25, 50, 75, 90, 95, 99, 100]
             , 
                "type": "hiding" ,
                "skillLevel": 100 ,
                "levels": [10, 25, 50, 65, 75, 80, 85, 90, 95, 99, 100]
            ]
        
    ]
);

// Here's the magic
Ext.each (users.records, function (user) 
    console.log ('*** USER ***');
    console.log (user);

    console.log ('id: ' + user.get ('id'));
    console.log ('name: ' + user.get ('name'));
    console.log ('age: ' + user.get ('age'));

    Ext.each (user.get ('skills'), function (skill) 
        console.log ('*** SKILL ***');
        console.log (skill);

        console.log ('type: ' + skill.type);
        console.log ('level: ' + skill.skillLevel);

        console.log ('*** LEVELS ***');
        Ext.each (skill.levels, function (level) 
            console.log (level);
        );
    );
);

这是一个 jsfiddle 来测试最后一个:jsfiddle

我希望能理解您的要求。如果我没有,请用你自己制作的例子告诉我;)

【讨论】:

优秀的例子和解释一切 - 非常感谢! 好的 :-) 如何将我的问题标记为已回答对我来说并不是很明显 @MicC 在“1 Answer”字样下有两个箭头和一个数字。如果您欣赏我的回答,您可以点击向上箭头给我奖励,否则如果您不喜欢它,只需点击向下箭头。最后,单击位于向下箭头下方的“V”按钮将您的问题标记为已回答,将其从灰色切换为绿色;)我们俩都将获得一些积分;) 显然我需要“15声望”才能点击向上箭头——我必须去杀龙救公主,对吧? :-) 15 个或更多? '因为你有 15 个 :P 但是,杀死一条龙并拯救一个公主可以帮助你!

以上是关于extjs 深入搜索商店数据?的主要内容,如果未能解决你的问题,请参考以下文章

ExtJS:如何将一个商店的记录插入另一个商店?

ExtJS 的 store 将所有数据保存在哪里

从单个商店动态创建多个 Sencha ExtJS 商店

Extjs - 如何填充组合框形成一个单一的商店?

ExtJS:使用一个网格加载多个商店

Extjs - 在添加带有商店数据的网格面板时获取“类型错误:名称未定义”