【问题标题】:Sencha Touch filter list view data storeSencha Touch 过滤器列表视图数据存储
【发布时间】:2011-12-24 22:15:25
【问题描述】:

所以我是 Sencha Touch 菜鸟,我可能已经过头了。我想做的是从一个主列表中过滤我拥有的数据,然后向下钻取。所以我有我的主要列表 - 类别。选择一个类别时,位置列出。我在让我的模型相互交谈时遇到问题(我认为)。就目前而言,如果我选择一个类别,我的所有数据都会返回,我想要的只是所选类别。我可以使用属性和指定值过滤我的商店。是否可以将值设置为我从类别菜单传递的变量?我已经cr了

这是我的代码:Category.js

app.views.CategoryList = Ext.extend(Ext.Panel, {
layout: 'card',
fullscreen: true,
scrolling: 'vertical',
initComponent: function() {
    //Check if device is a phone, if so only display the title since the viewport is smaller
     if (!Ext.is.Phone) {
            var listTemplate = '{post_type}';

      } else {
            var listTemplate = '{post_type}';

      }
    this.list = new Ext.List({
        grouped: false,
        indexBar: false,
        itemTpl: '{post_type}',
        store: app.stores.CategoryList,
        listeners: {
            selectionchange: {fn: this.onSelect, scope: this}
        }
    });

    ///selectionchange : function(){
       // this.store.filter('post_type', listTemplate)
        //this.onSelect('post_type')

    this.listpanel = new Ext.Panel({
        layout: 'fit',
        items: this.list,
        dockedItems: [{
            xtype: 'toolbar',
            title: listingTitle
        }],
        listeners: {
            activate: { fn: function(){
                this.list.getSelectionModel().deselectAll();
                Ext.repaint();
            }, scope: this }
        }
    });

    this.items = this.listpanel;

    app.views.CategoryList.superclass.initComponent.call(this);
},

onSelect: function(sel, records){
    if (records[0] !== undefined) {
            var categoryCard = new app.views.LocationsList({
                        store: app.stores.LocationList,
                        //store: app.stores.LocationList.filter('post_type',null),
                        prevCard: this.listpanel,
                        record: records[0]
                    });
                    this.setActiveItem(categoryCard, 'slide');


    }
}
});

Ext.reg('CategoryList', app.views.CategoryList);

LocationModel.js

//The model will load the locations information you entered in the locations.xml file         after it has been fed through JSON

//Register the Location Model
Ext.regModel('Locations', {
fields: [{name: 'post_title', type: 'string'},
         {name: 'post_type', type: 'string'}],
belongsTo: 'Category'
});
//Load XML data from JSON into local store
app.stores.LocationsList = new Ext.data.Store({
model: "Locations", //Model to use for the Store
/*filters: [
          {
              property: 'post_type',
              value: null
          }
      ],*/
sorters: [{
 property: 'post_title', //Set the title as a sorter to the listing card can use the grouped list layout
                direction: 'ASC'
            }],
proxy: {
    type: 'ajax', //Load JSON from our source defined in the config file
    url: HTTP_ROOT + '/' + JSON_SOURCE,
    reader: {
        type: 'json',
        root: 'markers1'
    },

    id  : 'LocationsID'
},
getGroupString : function(record) {
    // return the first character of the address in order to group
    return record.get('post_title')[0];
},

listeners: {
    'load': function (t, r, s) {
        //Fire custom event once all the load is complete
        Ext.dispatch({
            controller: app.controllers.map,
            action: 'loaded',
            records: r
        });
    },
},
  autoLoad : true //We start loading the info into the datastore immediately after the app is started to make it available ASAP

});

CategoryModel.js

//The model will load the locations information you entered in the locations.xml file   after it has been fed through JSON

Ext.regModel('Category', {
fields: [
{name: 'post_type', type: 'string'},],
hasMany: {
    model: 'Locations',
    name : 'locations',
    filterProperty: 'post_type'
}
});

var data = {
"categories":[
{"post_type":"trails"},
{"post_type":"Adventure Guides"},
{"post_type":"brew"},
{"post_type":"Festivals and Races"},
{"post_type":"Paddle and Rafting"},
{"post_type":"Parks and Forests"},
{"post_type":"Campgrounds"},
{"post_type":"Rivers, Mountains, Lakes"}
]
};

//Load XML data from JSON into local store
app.stores.CategoryList = new Ext.data.Store({
model: "Category", //Model to use for the Store
data: data,
sorters: [{
                property: 'post_type', //Set the title as a sorter to the listing card can use the grouped list layout
                direction: 'ASC'
            }],
proxy: {
    type: 'memory', //Load JSON from our source defined in the config file
    //url: HTTP_ROOT + '/' + JSON_SOURCE, 
    reader: {
        type: 'json',
        root: 'categories'
    },
    id  : 'CategoryID'
},
getGroupString : function(record) {
    // return the first character of the address in order to group
    return record.get('post_type')[0];
},

listeners: {
    'load': function (t, r, s) {
        //Fire custom event once all the load is complete
        Ext.dispatch({
            controller: app.controllers.map,
            action: 'loaded',
            records: r
        });
    },
},
autoLoad : true //We start loading the info into the datastore immediately after the app is started to make it available ASAP

});

【问题讨论】:

    标签: filter sencha-touch extjs


    【解决方案1】:

    所以看起来你正在接触 1.1,我现在正式生锈了,但我会试一试。我尝试使用 remotefilter 总是以泪水告终,所以我最终自己动手而不是尝试使用内置的过滤器方法。 YMMV。

    您可以获取商店和商店的代理,然后设置一个 extraParams 对象,该对象将被转换为获取参数。您也可以以这种方式修改 url。所以在过去我编写了自定义设置方法来过滤远程,因为它似乎比 touch1.1 内置函数更好。

    您将获取商店并将您的过滤器传递给如下方法:

    setFilterParams: function(param) {
      var p = this.getProxy();
      p.extraParams = {filter_value: param};
      // p.url also works
    }
    
    ... 
    yourstore.load();
    

    因此,即您的主列表使用 onitemtap 或 selectionchange 从第一个(未过滤的)存储中查找记录,获取该值并应用于您的详细信息页面使用的第二个存储上的 setFilter。

    还要注意,既然你说你是新手。这些存储代表单例,因此如果您有两个使用相同存储的列表,如果 list1 过滤存储上会影响 list2 的数据。

    【讨论】:

      【解决方案2】:

      以下是您在 Sencha Touch 1 中执行所需操作(用于两级过滤)的方法。

      //模型

      App.models.States = Ext.regModel('State', {
        idProperty : 'stateId',
        fields : [
          { name : 'stateId', type : 'integer'},
          { name : 'state', type : 'string'}
        ]
      });
      
      App.models.Districts = Ext.regModel('District', {
        fields : [
          { name : 'districtId', type : 'integer'},
          { name : 'stateId', type : 'integer'},
          { name : 'district', type : 'string'}
        ]
      });
      

      //商店

      App.stores.StatesStore = new Ext.data.Store({
        model : 'State',
        data : [
          { stateId : 1, state : 'Maharashtra' },
          { stateId : 2, state : 'Andhra Pradesh' }
        ],
        sorters : 'state',
        autoLoad : true
      });
      
      App.stores.DistrictStore = new Ext.data.Store({
        model : 'State',
        data : [
          { districtId : 1, district : 'Nasik', stateId : 1 },
          { districtId : 2, district : 'Thane', stateId : 1 },
          { districtId : 3, district : 'Jalgaon', stateId : 1 },
          { districtId : 4, district : 'Hyderabad', stateId : 2 },
          { districtId : 5, district : 'Nizamabad', stateId : 2 },
          { districtId : 6, district : 'Kurnool', stateId : 2 }
        ],
        sorters : 'district',
        autoload : true
      });
      

      我已在此处内联加载数据,以便您查看它们是如何关联的。现在,每个地区 id 都与一个州 id 相关联。例如,纳西克区位于马哈拉施特拉邦内。因此,“Nasik”的 DistrictID 1 现在与“Maharashtra”的 stateId 1 相关联。

      //对于州和地区的选择字段

      {
       xtype: 'selectfield',
       name : 'state',
       id : 'state',
       label: 'State',
       store : App.stores.StatesStore,
       displayField : 'state',
       valueField : 'stateId',
       listeners : {
          change : function(t, value){
              Ext.dispatch({
                  controller : 'Users',
                  action : 'filterLocations',
                  data : {value:value, level : 'district'}
              });
          }
       }
      },
      {
        xtype: 'selectfield',
        name : 'district',
        id : 'district',
        label: 'District',
        store : App.stores.DistrictStore,
        displayField : 'district',
        valueField : 'districtId'
      }
      

      现在选择字段已与我们之前创建的模型/商店相关联。

      我们现在来看看当状态的选择字段改变时调用的控制器函数。

      filterLocations: function(params){
          var value = params.data.value;
          var level = params.data.level;
      
          if(level == "district"){
              App.stores.DistrictStore.clearFilter();
              App.stores.DistrictStore.filter('stateId', value);
              var firstValue = Ext.getCmp('district').store.getAt(0);
              if(firstValue) Ext.getCmp('district').setValue('Select District');
          }
          else if(level == "block"){
              App.stores.BlockStore.clearFilter();
              App.stores.BlockStore.filter('districtId', value);
              var firstValue = Ext.getCmp('block').store.getAt(0);
              if(firstValue) Ext.getCmp('block').setValue('Select Block');
          }
      },
      

      我为您提供了一个扩展控制器,它可以支持多个级别。例如,州将过滤地区,地区可以过滤村庄等。因此,在控制器中,我们需要进行过滤的级别。如果要在州和地区之间进行过滤,则将调用第一个 if 条件,并且将过滤地区存储(以及因此选择字段)以获得所需的值。

      【讨论】:

      • 您也可以将此模型/商店/控制器概念扩展到 Sencha Touch 2。我现在没有现成的例子,但应该相对容易。
      猜你喜欢
      • 2012-09-13
      • 2015-11-10
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多