2013-10-03 4 views
0

Я хочу применить фильтр на Ext.Data.TreeStore. Модель, которую использует хранилище деревьев, имеет свойство с именем «ID» & на основе этого «ID». Я хочу применить фильтр в хранилище деревьев.Применение фильтра в Ext.Data.TreeStore в ExtJS 4.1

Я посмотрел на следующие ссылки:

Filter 1

Filter 2

Но эти варианты не работают.

В магазине «загрузка», я добавил следующий код.

'load': function (thisStore, records, successful, eOpts) { 

      var v = 'Product'; 
      var count = 0; 
      thisStore.filterBy(function (record) { 
       count++; 
       return record.data.ID == v; 
      }); 
      alert(count); 
     } 

Но граф всегда приходит как 0.

Мое дерево выглядит следующим образом:

Ext.create('Ext.tree.Panel', { 
    title: 'Simple Tree', 
    width: 200, 
    height: 150, 
    store: store, 
    rootVisible: false, 
    renderTo: Ext.getBody(), 
    plugins:[Ext.create('plugin.treefilter',{ 
     pluginId: 'treefilter', 
     allowParentFolders: true 
    })] 
}); 

плагин:

Ext.define('Ext.ux.TreeFilter', { 
    extend: 'Ext.AbstractPlugin', 
    alias: 'plugin.treefilter', 




    collapseOnClear: false, // collapse all nodes when clearing/resetting the filter 




    allowParentFolders: false, // allow nodes not designated as 'leaf' (and their child items) to be matched by the filter 




    init: function (tree) { 
     var me = this; 
     me.tree = tree; 




     tree.filter = Ext.Function.bind(me.filter, me); 
     tree.clearFilter = Ext.Function.bind(me.clearFilter, me); 
     tree.filterBy = Ext.Function.bind(me.filterBy,me); 
    }, 


    filter: function (value, property, re) { 
     var me = this; 
     if (Ext.isEmpty(value)) { // if the search field is empty 
      me.clearFilter(); 
      return; 
     } 

     property = property || 'text';// property is optional - will be set to the 'text' propert of the treeStore record by default 
     re = re || new RegExp(value, "ig"); // the regExp could be modified to allow for case-sensitive, starts with, etc. 

     // iterate over all nodes in the tree in order to evalute them against the search criteria 
     me.filterBy(function(node){ 
      return node.get(property).match(re);// if the node matches the search criteria and is a leaf (could be modified to searh non-leaf nodes) 
     }); 

    }, 

    filterBy: function (fn,scope){ 


     var me = this, 
      tree = me.tree, 
      matches = [], // array of nodes matching the search criteria 
      root = tree.getRootNode(), // root node of the tree 
      visibleNodes = [], // array of nodes matching the search criteria + each parent non-leaf node up to root 
      viewNode; 


     if (!fn) { // if no fn defined 
      me.clearFilter(); 
      return; 
     } 




     tree.expandAll(); // expand all nodes for the the following iterative routines 



     //fn.call(scope || me, record) 
     root.cascadeBy(function (node){ 
      if(fn.call(scope || me, node)){ 
       matches.push(node);// add the node to the matches array 
      } 
     }); 

     if (me.allowParentFolders === false) { // if me.allowParentFolders is false (default) then remove any non-leaf nodes from the regex match 
      Ext.each(matches, function (match) { 
       if (match !== undefined) { 
        if (!match.isLeaf()) { 
         Ext.Array.remove(matches, match); 
        } 
       } 
      }); 
     } 



     Ext.each(matches, function (item, i, arr) { // loop through all matching leaf nodes 
      root.cascadeBy(function (node) { // find each parent node containing the node from the matches array 
       if (node.contains(item) === true) { 
        visibleNodes.push(node); // if it's an ancestor of the evaluated node add it to the visibleNodes array 
       } 
      }); 

/* Commented out because this shows all children whether or not they pass the filter 
      if (me.allowParentFolders === true && !item.isLeaf()) { // if me.allowParentFolders is true and the item is a non-leaf item 
       item.cascadeBy(function (node) { // iterate over its children and set them as visible 
        visibleNodes.push(node); 
       }); 
      } 
*/ 
      visibleNodes.push(item); // also add the evaluated node itself to the visibleNodes array 
     }); 




     root.cascadeBy(function (node) { // finally loop to hide/show each node 
      viewNode = Ext.fly(tree.getView().getNode(node)); // get the dom element assocaited with each node 
      if (viewNode) { // the first one is undefined ? escape it with a conditional 
       viewNode.setVisibilityMode(Ext.Element.DISPLAY); // set the visibility mode of the dom node to display (vs offsets) 
       viewNode.setVisible(Ext.Array.contains(visibleNodes, node)); 
      } 
     }); 
    }, 


    clearFilter: function() { 
     var me = this, 
      tree = this.tree, 
      root = tree.getRootNode(), 
      viewNode; 




     if (me.collapseOnClear) { 
      tree.collapseAll(); 
     } // collapse the tree nodes 
     root.cascadeBy(function (node) { // final loop to hide/show each node 
      viewNode = Ext.fly(tree.getView().getNode(node)); // get the dom element assocaited with each node 
      if (viewNode) { // the first one is undefined ? escape it with a conditional and show all nodes 
       viewNode.show(); 
      } 
     }); 
    } 
}); 

Пожалуйста, предложите изменения мне нужно make, чтобы я мог фильтровать TreeStore.

+0

после просмотра в ExtJS документации. Я не нашел плагина для древовидной железы. вы уверены, что он существует? – peernohell

+0

Неудивительно, что 'count' приходит как 0, посмотрите [код] (http://docs.sencha.com/extjs/4.1.3/source/AbstractStore.html#Ext-data-AbstractStore-method-filterBy)! Вероятно, именно поэтому они пометили этот метод как частный в хранилище деревьев. – rixo

+0

@peernohell: Я добавил код плагина. – SharpCoder

ответ

1

Вы должны реализовать что-то самостоятельно ... Вот filterBy метод, который будет работать. Обратите внимание, что, в отличие от обычного фильтра хранилища, он не сохраняет ссылку на отфильтрованный узел (следовательно, метод clearFilter). Если вам что-то нужно, вам придется приспособиться.

Fiddle here

var store = Ext.create('Ext.data.TreeStore', { 
    root: { 
     expanded: true, 
     children: [ 
      { text: "detention", leaf: true }, 
      { text: "homework", expanded: true, children: [ 
       { text: "book report", leaf: true }, 
       { text: "algebra", leaf: true} 
      ] }, 
      { text: "buy lottery tickets", leaf: true } 
     ] 
    } 
}); 

var tree = Ext.create('Ext.tree.Panel', { 
    title: 'Simple Tree', 
    width: 200, 
    height: 150, 
    store: store, 
    rootVisible: false, 
    renderTo: Ext.getBody() 

    /** 
    * Filters the tree recursively with the given function. 
    * 
    * @param {Function} fn 
    * @param {Object} [scope] 
    */ 
    ,filterBy: function(fn, scope) { 
     scope = scope || this; 

     function applyFilter(node) { 
      var out = []; 
      Ext.each(node.childNodes, function(child) { 
       if (fn.call(scope, child)) { 
        applyFilter(child); 
       } else { 
        // we can't remove child right away, that would 
        // kill the loop 
        out.push(child); 
       } 
      }); 
      Ext.each(out, function(child) { 
       // destroy, and suppressEvent 
       node.removeChild(child, true, true); 
      }); 
     } 

     applyFilter(this.getRootNode()); 
    } 
}); 

// example 
tree.filterBy(function(record) { 
    return record.get('text').indexOf('o') !== -1; 
}); 
+0

Благодарим за быстрый ответ. Я вызвал filterBy() в событии загрузки магазина. Я использую этот код: 'load': function (thisStore, records, successful, eOpts) {var v = 'Product'; var count = 0; thisStore.filterBy (функция (запись) { alert ('there'); count ++; return record.data.ID == v; }); } Но система никогда не отображает предупреждающее сообщение, что означает, что эта функция не вызвана :(.Я делаю что-то не так? – SharpCoder

+0

С моим кодом метод 'fiterBy' должен вызываться из древовидного компонента, а не из его магазина. учитывая код плагина, который вы разместили ... Вы уверены, что на вашем дереве есть какие-то данные? Вы видите некоторые узлы? – rixo

+0

Я все еще не в состоянии это сделать. Я создал скрипку. было бы здорово, если бы вы могли помочь мне исправить это. http://jsfiddle.net/BYqRN/22/ – SharpCoder

Смежные вопросы