<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"  href="/xslt/final.xslt"?><html>
  <head>
    <title>11.2 Навигация по DOM в ExtJS. Разборки с Element/CompositeElement</title>
    <meta name="css" content="/doc/ext/ext_examples.css"/>
    <meta name="js" content="/js/EXT4/ext-all.js;/doc/ext/155.js"/>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="id" content="63"/>
    <link rel="stylesheet" type="text/css" href="/doc/ext/ext_examples.css"/>
    <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml"/>
  </head>
  <body>
    <div class="main">
      <div class="wrap">
        <div class="L">
          <h1><a href="/">..</a> / 11.2 Навигация по DOM в ExtJS. Разборки с Element/CompositeElement</h1>
          <ol class="tags big">
            <li>
              <a href="/ExtJS-4">ExtJS-4</a>
            </li>
          </ol>
          <div class="myContent"><h2>
  Цепочки запросов в ExtJS
</h2>
<p>
  Разборки с Ext.core.Element заняли у меня слишком много времени,
  потому что зациклился на поиске привычных по jQuery методов
  навигации по DOM в виде цепочек запросов:
</p>
<pre class="brush: js">
var parent=$('#someID');
var tables=parent.find('table'); … /* делаем что-то с табличками */
var forms=tables.find('form');   … /* делаем что-то с формами */
var input=form.find('input');   …  /* делаем что-то с input */
</pre>
<p>
  Найти вменяемый аналог в ExtJS мне так и не удалось.
  Слабовменяемый способ такой:
</p>
<pre class="brush: js">
var parent=Ext.query('#ex1');
var table = Ext.query('table',parent);
var form=Ext.query('form',table);
var input=Ext.query('input',form); Ext.get(input).setStyle({'border':'5px solid red'})
</pre>
<p>
  В первой строке определяю DOM родительского элемента.<br/>
  Во 2-3 строке используя DOM родительского элемента в качестве
  отправной точки поиска ищу соответствующий дочерний
  элемент.<br/>
  В последней строке преобразую DOM в объект Ext.core.Element, и
  уже с ним выполняю какую-то операцию.<br/>
  Причем если в цепочке результат какой-нибудь операции будет не в
  единственном числе, нужно вводить цикл.
</p>
<p>
  Судя по тому что пишут в форуме Ext и тому, что разработчики Ext
  ввели специальные адаптеры для использования jQuery, Prototype и
  др., я - не единственный кто столкнулся с этой проблемой.
</p>
<p>
  А в остальном многие из методов Ext.core.Element и
  Ext.CompositeElement для навигации по DOM иногда работают
  предсказуемо. Но не всегда
</p>
<h2>
   1. parent, prev, next, child для Ext.core.Element
</h2>
<pre class="brush: js">
var сhild1=Ext.get('#ex1').child('div'); // !! ПЕРВЫЙ дочерний элемент
        child1.createChild(' &lt;b&gt;select «#ex1 child»&lt;/b&gt;');
var ex1b=Ext.get('ex1b');
ex1b.next().createChild(' &lt;b&gt;select «#ex1b next»&lt;/b&gt;'); // следующий сосед
ex1b.prev().createChild(' &lt;b&gt;select «#ex10 prev»&lt;/b&gt;'); // предыдущий сосед
ex1b.parent().setStyle({'border':'5px solid red'}); // родительский элемент
</pre>
<pre class="brush: js">
</pre>
<div id="ex2">
  <div id="ex2a" class="domexample ex2-childs">
    #ex1 &gt; #ex1a
  </div>
  <div id="ex2b" class="domexample ex2-childs">
    #ex1 &gt; #ex1b
  </div>
  <div id="ex2c" class="domexample ex2-childs">
    #ex1 &gt; #ex1c
  </div>
</div>
<div id="ex1">
  <div id="ex1a" class="domexample ex1-childs">
    #ex1 &gt; #ex1a
  </div>
  <div id="ex1b" class="domexample ex1-childs">
    #ex1 &gt; #ex1b
  </div>
  <div id="ex1c" class="domexample ex1-childs">
    #ex1 &gt; #ex1c
  </div>
</div>
<p>
  Эти методы применимы к Ext.core.Element! Т.е. к результату
  полученному при помощи Ext.get(). Ошибкой было бы по привычке
  думать, что эти методы так же применимы к результату более
  универсального Ext.select(). Ext.select() возвращает совершенно
  другой объект Ext.CompositeElement, к которому эти методы
  напрямую неприменимы.
</p>
<h2>
   2. Ext.each для Ext.CompositeElement
</h2>
<p>
  Итератор Ext.each - отдельный метод ExtJS, среди прочего он
  позволяет перебирать результаты DOM-выборки. Я разберу пример
  только для Ext.CompositeElement
</p>
<div class="domexample ex3">
   div.ex3
</div>
<div class="domexample ex3">
   div.ex3
</div>
<div class="domexample ex3">
   div.ex3
</div>
<pre class="brush: js">
 var ex3=Ext.select('.ex3'); ex3.each(function(el,c,index){
          this.createChild(' &lt;b&gt;«.ex3 ('+ index+')»&lt;/b&gt;');
      // здесь this - применительно к текущему элементу набора Ext.CompositeElement
         });
………………

</pre>
<div class="ex3">
   div.ex3
</div>
<div class="ex3">
   div.ex3
</div>
<div class="ex3">
   div.ex3
</div>
<p>
  Подробнее о праметрах функции each применительно к данному
  примеру можно посмотреть <a href="https://a.saveliev-ext.xdev.chronopay.com/EXT4/docs/index.html#/api/Ext.CompositeElement-method-each">
  здесь</a>
</p>
<h2>
   3. filter,add,… для Ext.CompositeElement
</h2>
<p>
  Похожие, но не аналогичные методы выборки есть и в jQuery:
</p>
<ul>
  <li>
    <strong>filter</strong> - отфильтровывает из набора
    Ext.CompositeElement те элементы, которые соответствуют образцу
    выбора CSS/XPath
  </li>
  <li>
    <strong>add</strong> - добавляет в набор Ext.CompositeElement
  </li>
  <li>clear - удаляет элементы из набора Ext.CompositeElement, при
  этом не трогает сами DOM-элементы
  </li>
  <li>getCount - количество элементов в выборке
  </li>
  <li>each - см. выше
  </li>
  <li>…………………………….
  </li>
</ul>
<p>
  Характерно, что всего методов у Ext.CompositeElement (ExtJS
  4.0.3) ровно тринадцать. Несчастливое число. Ниже приведу пример
  работы некоторых из них без комментариев.
</p>
<pre class="brush: js">
 var ex4=Ext.select('.ex4');             // создается первичный набор  CompositeElement
 ext4.add('.ex5').add('.ex6');          // к нему добавляются доп. выборки ex4.each(function(el,c,index){               // перебираю полученный набор
          this.createChild(' &lt;b&gt;«.exAdd  ('+ index+')»&lt;/b&gt;');
         });
 var ex5=ex4.filter('.exFilter');   // выбираю из набора только те элементы,
                                                                        // которые имеют CSS -класс exFilter ex5.each(function(el,c,index){            // перебираю полученный набор
          this.createChild(' &lt;b&gt;«.exFilter  ('+ index+')»&lt;/b&gt;');
         });
………………………
</pre>
<div class="ex4 exFilter">
  .ex4.exFilter
</div>
<div class="ex5 exFilter">
  .ex5.exFilter
</div>
<div class="ex6" id="rem">
  .ex6
</div>
<div class="ex4 exFilter domexample">
  .ex4.exFilter
</div>
<div class="ex5 exFilter domexample">
  .ex5.exFilter
</div>
<div class="ex6 domexample" id="rem" style="margin-bottom:1em;">
  .ex6
</div>
<p>
  UPD<br/>
   И все-таки это - жопа! Без дырки.
</p>
<h2>
  Далее
</h2>
<ol>
  <li>
    <a href="/64.htm">Манипуляции с DOM. Часть 1. Установка/чтение
    стилей, классов, атрибутов</a>
  </li>
  <li>
    <a href="/65.htm">Манипуляции с DOM. Часть 2.
    Добавление/удаление и пр. операции с узлами</a>
  </li>
</ol></div>
          <ol class="tags big">
            <li class="date">2011-12-11</li>
            <li>
              <a href="/ExtJS-4">ExtJS-4</a>
            </li>
          </ol>
          <ol class="see">
            <li>
              <a href="#"><span>www.sencha.com/learn/domquery-v11-basics/</span> - <b>sencha.com DomQuery v1.1 Basics</b></a>
            </li>
            <li>
              <a href="#"><span>docs.sencha.com/ext-js/4-0/#!/api/Ext.CompositeElement-method-each</span> - <b>sencha.com Ext.CompositeElement</b></a>
            </li>
            <li>
              <a href="#"><span>www.sencha.com/learn/domquery-v11-basics/</span> - <b>sencha.com Ext.DomQuery</b></a>
            </li>
          </ol>
          <ul class="comment"/>
        </div>
      </div>
      <div class="R">
        <a href="/" title="&#x41D;&#x430; &#x433;&#x43B;&#x430;&#x432;&#x43D;&#x443;&#x44E;"/>
      </div>
    </div>
    <div id="li"/>
  </body>
</html>

