<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Блог маленького, но очень отважного программиста &#187; ExtJS</title>
	<atom:link href="http://xo66ut.ru/archives/category/extjs/feed" rel="self" type="application/rss+xml" />
	<link>http://xo66ut.ru</link>
	<description>PHP, MySQL, Javascript, JQuery, ExtJS, UML, и другие интернетости...…</description>
	<lastBuildDate>Tue, 04 Oct 2011 08:40:28 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Анонсирован Ext JS 3.3 Beta</title>
		<link>http://xo66ut.ru/archives/469</link>
		<comments>http://xo66ut.ru/archives/469#comments</comments>
		<pubDate>Thu, 29 Jul 2010 06:43:39 +0000</pubDate>
		<dc:creator>Xo66uT</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Sencha]]></category>
		<category><![CDATA[Новости]]></category>
		<category><![CDATA[Component]]></category>
		<category><![CDATA[Ext.grid]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://xo66ut.ru/?p=469</guid>
		<description><![CDATA[В этом релизе сделано более 160 багфиксов и сделано несколько полезных компонентов.
PivotGrid.

&#8220;Первый компонент, который мы хотели бы представить это PivotGrid. Это компонент является инструментом обобщения данных, он идеально подходит для удобной организации больших объемов данных. PivotGrid поможет вам и вашим пользователям суммировать данные любого количества полей, а также легко разбить даннные, например, по параметрам город, [...]]]></description>
			<content:encoded><![CDATA[<p>В этом релизе сделано более 160 багфиксов и сделано несколько полезных компонентов.</p>
<h3>PivotGrid.</h3>
<p style="text-align: center;"><a href="http://sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/simple.html"><img class="aligncenter" src="http://www.sencha.com/blog/wp-content/uploads/2010/07/pivotgrid.png" alt="PivotGrid" width="250" height="154" /></a></p>
<p>&#8220;Первый компонент, который мы хотели бы представить это PivotGrid. Это компонент является инструментом обобщения данных, он идеально подходит для удобной организации больших объемов данных. PivotGrid поможет вам и вашим пользователям суммировать данные любого количества полей, а также легко разбить даннные, например, по параметрам город, год квартал. Посмотрите на пример по ссылке, там мы суммируем данные о продажах. PivotGrid легко интегрируются в уже существующие магазины, а создаются всего с помощью нескольких строк кода. Мы создали ряд примеров, демонстрирующих различные возможности компонента. Вот небольшой пример как можно создать таблицу из примера.&#8221;</p>
<p><strong>Личное мнение</strong>: Акцентрируется внимание на том, что компонент работает с большими объемами данных, но в примере компонент грузит данные довольно продолжительное время, отсюда возникает вопрос, а есть ли заявленный profit ?</p>
<pre class="brush: jscript;">
var pivotGrid = new Ext.grid.PivotGrid({
    title     : 'PivotGrid example',
    store     : myStore,
    aggregator: 'sum',
    measure   : 'value',

    leftAxis: [
        {dataIndex: 'person',  width: 80},
        {dataIndex: 'product', width: 90}
    ],

    topAxis: [
        {dataIndex: 'year'},
        {dataIndex: 'city'}
    ]
});
</pre>
<h3>Компонент Календарь.</h3>
<p style="text-align: center;"><a href="http://sencha.com/deploy/ext-3.3-beta1-6976/examples/calendar/index.html"><img class="aligncenter" src="http://www.sencha.com/blog/wp-content/uploads/2010/07/calendar.gif" alt="Компонент Calendar" width="250" height="184" /></a></p>
<p>&#8220;Многие разработчики просили нас сделать официальную поддержку компонента Calendar. Календари это открытый вопрос: Есть много способов их реализации и много функций, которые можно добавить. Мы рады вам представить новый компонент для отображения событий за день, неделю и месяц, все они представлены в примере компонента. Также как и с компонентом PivotGrid, новый компонент Calendar предназначен для работы с уже готовым набором данных, что означает легкую интеграцию с уже существующим кодом. Мы пока не включили компонент Calendar в ext-all.js, но включили рабочие версии этих компонентов в examples/calendar директории SDK.&#8221;</p>
<p><strong>Личное мнение</strong>: по функционалу календарь пока значительно уступает проприетарному компоненту sheduler, но решение по разработке собственного компонента, очень хороший шаг, его не хватало.</p>
<h3>Еще кое-что.</h3>
<p style="text-align: center;"><a href="http://sencha.com/deploy/ext-3.3-beta1-6976/examples/grid/array-grid.html"><img class="aligncenter" src="http://www.sencha.com/blog/wp-content/uploads/2010/07/actioncolumn.gif" alt="ActionColumn" width="250" height="159" /></a></p>
<p>&#8220;В дополение к этим двум компонентам в новой версии в Grid появился новый тип столбца ActionColumn. В этом типе столбцов рисуются иконки, к которым можно приписать любые функции для манипуляции с Grid. Например, как показано в примере, на двух кнопках работают функции покупки \ продажи. Как и в предыдущий версиях, обратная совместимость является для нас приоритетной задачей. Для нормальной работы нового компонента PivotGrid были внесены изменения в GridView, который, как известно, являлся причиной некорректного поведения в некоторых ситуациях, но все эти проблемы буду исправлены в финальной версии.&#8221;</p>
<p><em>Источник <a href="http://www.sencha.com/blog/2010/07/28/announcing-ext-js-3-3-beta-pivotgrids-calendars-and-more/" target="_blank">http://www.sencha.com/blog/2010/07/28/announcing-ext-js-3-3-beta-pivotgrids-calendars-and-more/</a></em></p>
<img src="http://xo66ut.ru/?ak_action=api_record_view&id=469&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://xo66ut.ru/archives/469/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ExtJS теперь Sencha</title>
		<link>http://xo66ut.ru/archives/432</link>
		<comments>http://xo66ut.ru/archives/432#comments</comments>
		<pubDate>Thu, 17 Jun 2010 10:35:46 +0000</pubDate>
		<dc:creator>Xo66uT</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Sencha]]></category>
		<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://xo66ut.ru/?p=432</guid>
		<description><![CDATA[Ext JS + jQTouch + Raphaël = Sencha

&#8220;Интересные вещи происходят! сегодня мы объединяем силы с проектами jQTouch и Raphaël, а также меняем имя домена проекта с extjs.com на sencha.com. Эти проекты лидируют в своих областях и мы рады видеть в своих рядах их создателей Девида Канеду и Дмитрия Барановского. Мы считаем, что это сотрудничество приведет [...]]]></description>
			<content:encoded><![CDATA[<h2>Ext JS + jQTouch + Raphaël = Sencha</h2>
<p style="text-align:center;"><img class="aligncenter size-full wp-image-433" title="ext_js-sencha" src="http://xo66ut.ru/wp-content/uploads/2010/06/ext_js-sencha.jpg" style="border: 0" alt="" width="383" height="265" /></p>
<p>&#8220;<em>Интересные вещи происходят! сегодня мы объединяем силы с проектами jQTouch и Raphaël, а также меняем имя домена проекта с extjs.com на sencha.com. Эти проекты лидируют в своих областях и мы рады видеть в своих рядах их создателей Девида Канеду и Дмитрия Барановского. Мы считаем, что это сотрудничество приведет к впечатляющим результатам. &#8230; Sencha эт0 новое название нашей компании, а также разновидность япоского зеленого чая (</em>Так вот он какой стратегический напиток ExtJS разработчика ?!<em>). </em></p>
<p><em>Развитие Ext JS, Ext GWT, Designer, Direct и остального будет продолжаться, думаем только над переименованием Ext JS Designer на Sencha Designer. Одним из преимуществ переименования для нас является то, что мы разделяем названия компании и продукта. </em></p>
<p><em>Проекты jQTouch и Raphaël так и останутся под лицензией MIT. Мы создаем Sencha Labs подразделение, которое будет заниматься торговыми марками и авторскими правами всех некоммерческих проектов связанных с Sencha. Мы также рады сообщить, что Джонатан Старк известный разработчик мобильных приложений и автор двух книг под редакцией O’Reilly станет руководителем jQTouch (Добро пожаловать на борт Джонатан)</em>&#8221; &#8211; вот такое сообщение получили зарегистрированные на форуме Ext JS, позже оно было опубликовано и на сайте.</p>
<p>Что можно ожидать от объединения ? Я думаю только хороших новых результатов. jQTouch это jQuery плагин для разработки под мобильные девайсы типа iPhone, iPad и прочие «forward-thinking» девайсы. Как поможет эта библиотека в развитии Ext JS пока соевершенно не ясно. А Raphaël это крутая штука для разработки векторной графики под веб. Подключение этого проекта позволит модифицировать компоненты для построение графиков и диаграмм Ext JS, которые сейчас работают с помощью Flash.</p>
<p>Есть также мнение, что переименование связано с тем, что из компании ушел ее основатель Джек Слокум, или вся команда разработчиков ушла от него в новую компанию Sencha. Вот что пишут про это на сайте: &#8220;<em>После интенсивной работы над развитием ExtJS, за последние 18 месяцев  Джек стремительно прекратил свое участие. Хоть он и может вернуться на  некоторых условиях, мы желаем ему всего наилучшего.</em>&#8221;</p>
<p>В любом случае, что же действительно будет дальше покажет время.</p>
<img src="http://xo66ut.ru/?ak_action=api_record_view&id=432&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://xo66ut.ru/archives/432/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Динамическая загрузка файлов &#8211; AJAX Upload</title>
		<link>http://xo66ut.ru/archives/368</link>
		<comments>http://xo66ut.ru/archives/368#comments</comments>
		<pubDate>Fri, 30 Apr 2010 11:40:39 +0000</pubDate>
		<dc:creator>Xo66uT</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[userfriendly]]></category>

		<guid isPermaLink="false">http://xo66ut.ru/?p=368</guid>
		<description><![CDATA[
В размышлениях об интерактивности задавался мыслью как сделать удобный с точки зрения usability загрузчик файлов.  Плюс подогревал интерес к механизму работы ajax загрузчика в ExtJS. Делая однажды чат и разобравшись в ограничениях браузеров, узнал, что нет возможности отправлять файл по средством объекта xmlhttprequest. Поэтому было непонятно, как ExtJS uploader отправляет файлы, как будто делает это [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://xo66ut.ru/wp-content/uploads/2010/04/ajax_upload-e1272627550877.jpg"><img class="aligncenter size-full wp-image-376" title="ajax_upload" src="http://xo66ut.ru/wp-content/uploads/2010/04/ajax_upload-e1272627550877.jpg" alt="AJAX-Upload" width="543" height="282" /></a></p>
<p><a href="http://xo66ut.ru/wp-content/uploads/2010/04/ajax_upload-e1272627550877.jpg"></a>В размышлениях об интерактивности задавался мыслью как сделать удобный с точки зрения usability загрузчик файлов.  Плюс подогревал интерес к механизму работы <strong>ajax </strong>загрузчика в <strong>ExtJS</strong>. Делая однажды чат и разобравшись в ограничениях браузеров, узнал, что нет возможности отправлять файл по средством объекта <strong>xmlhttprequest</strong>. Поэтому было непонятно, как <strong>ExtJS </strong>uploader отправляет файлы, как будто делает это через <strong>ajax</strong>. Работая над созданием чата, я также ознакомиться с другими ограничениями браузеров, например на количество одновременных запросов к одному домену (ограничены двумя запросами), а также со всевозможными способами обхода этого ограничения. Там же для удобства применялся <strong>iframe </strong>транспорт, который позволяет отправлять обычные <strong>POST </strong>запросы через невидимый (0 px на 0 px) <strong>iframe</strong>. После этого мне сразу стал понятен механизм работы загрузчика файлов в <strong>ExtJS</strong>.<span id="more-368"></span></p>
<p>Решил добавить юзабильности в один из проектов и использовать этот способ для загрузки файлов, благо есть готовый плагин, называющийся <strong><a href="http://valums.com/ajax-upload/" target="_blank">AJAX Upload</a></strong>, хотя как я уже писал <strong>ajax </strong>тут не причем, все реализовано следующим образом:</p>
<ul>
<li> Плагин создает невидимый <strong>input </strong>над элементом, к которому вы привязываете нагрузку. То есть когда вы нажимаете на кнопку, появляется окно со стандартным выбором файла.</li>
<li>Затем когда вы выбираете файл плагин отправляет форму содержащую <strong>input </strong>с файлом через <strong>iframe</strong>.</li>
</ul>
<p><em>&#8220;Обычно для закачки файлов мы используем file input (&lt;input type=”file” /&gt;), его проблематично стилизовать. В современных веб приложениях этот input выглядит устаревшим. Можно конечно использовать для загрузки <strong>Flash</strong>, но <strong>Javascript </strong>прекрасно решает эту задачу. Плагин <strong>AJAX-Upload </strong>позволяет легко загружать несколько файлов без перезагрузки страницы. Он работает во всех браузерах и не требует никаких дополнительных библиотек для работы. К тому же он не затрагивает глобальных <strong>namespace</strong>&#8216;ов и прекрасно работает вместе с <strong>jQuery </strong>и <strong>Prototype</strong>.&#8221;</em></p>
<p>Работать с плагином довольно легко. Достаточно создать любой <strong>DOM </strong>элемент и привязать к нему плагин. Плагин отправляет файлы в виде обычного <strong>POST </strong>запроса. Поэтому можно обрабатывать их загрузку на любом серверном языке. На сайте плагина много работающий примеров. В плагине даже реализовано ограничение на расширения загружаемых файлов.</p>
<p>Распространяется плагин свободно под лицензией <strong>MIT</strong>.</p>
<img src="http://xo66ut.ru/?ak_action=api_record_view&id=368&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://xo66ut.ru/archives/368/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Раширение классов в ExtJS</title>
		<link>http://xo66ut.ru/archives/275</link>
		<comments>http://xo66ut.ru/archives/275#comments</comments>
		<pubDate>Fri, 23 Apr 2010 07:12:51 +0000</pubDate>
		<dc:creator>Xo66uT</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Перевод]]></category>
		<category><![CDATA[Ext.extend]]></category>
		<category><![CDATA[xtype]]></category>

		<guid isPermaLink="false">http://xo66ut.ru/?p=275</guid>
		<description><![CDATA[Цель.
Давайте добавим функциональности к Ext.form.Combobox, сделаем так, чтобы перед каждым элементом списка отображалась иконка.

Давайте назовем наш плагин Ext.ux.IconCombo, а также зарегистрируем для него xtype iconcombo.

Создаем файлы.
Наш первый шаг заключается в том, чтобы подготовить файлы для нашего плагина.

iconcombo.html: HTML код приложения, которое будет содержать наш плагин. Чтобы сделать этот пример более простым, этот файл также будет [...]]]></description>
			<content:encoded><![CDATA[<h2>Цель.</h2>
<p>Давайте добавим функциональности к Ext.form.Combobox, сделаем так, чтобы перед каждым элементом списка отображалась иконка.<br />
<a href="http://xo66ut.ru/wp-content/uploads/2010/04/IconComboExt2.png"><img class="aligncenter size-full wp-image-346" title="IconComboExt2" src="http://xo66ut.ru/wp-content/uploads/2010/04/IconComboExt2.png" alt="ExtJS Combobox" width="175" height="97" /></a></p>
<p>Давайте назовем наш плагин <strong>Ext.ux.IconCombo</strong>, а также зарегистрируем для него <strong>xtype</strong> <strong>iconcombo</strong>.</p>
<p><span id="more-275"></span></p>
<h2>Создаем файлы.</h2>
<p>Наш первый шаг заключается в том, чтобы подготовить файлы для нашего плагина.</p>
<ul>
<li><strong>iconcombo.html</strong>: HTML код приложения, которое будет содержать наш плагин. Чтобы сделать этот пример более простым, этот файл также будет содержать Javascript код и CSS. В реальном приложении нужно хранить отдельно код и стили.</li>
<li><strong>Ext.ux.IconCombo.js: </strong>Javascript код нашего плагина.</li>
</ul>
<h2>iconcombo.html</h2>
<pre class="brush: xml;">
&lt;html&gt;
&lt;head&gt;
    &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
    &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;../extjs-2.0/resources/css/ext-all.css&quot;&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;../extjs-2.0/adapter/ext/ext-base.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;../extjs-2.0/ext-all-debug.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;Ext.ux.IconCombo.js&quot;&gt;&lt;/script&gt;

    &lt;style type=&quot;text/css&quot;&gt;
    .ux-flag-us {
        background-image:url(../img/flags/us.png) ! important;
    }
    .ux-flag-de {
        background-image:url(../img/flags/de.png) ! important;
    }
    .ux-flag-fr {
        background-image:url(../img/flags/fr.png) ! important;
    }
    .ux-icon-combo-icon {
        background-repeat: no-repeat;
        background-position: 0 50%;
        width: 18px;
        height: 14px;
    }

    /* X-BROWSER-WARNING: this is not being honored by Safari */
    .ux-icon-combo-input {
        padding-left: 25px;
    }

    .x-form-field-wrap .ux-icon-combo-icon {
        top: 3px;
        left: 5px;
    }
    .ux-icon-combo-item {
        background-repeat: no-repeat ! important;
        background-position: 3px 50% ! important;
        padding-left: 24px ! important;
    }
    &lt;/style&gt;

    &lt;script type=&quot;text/javascript&quot;&gt;
Ext.BLANK_IMAGE_URL = '../extjs-2.0/resources/images/default/s.gif';
Ext.onReady(function() {
    var win = new Ext.Window({
        title:'Icon Combo Ext 2.0 Extension Class Example',
        width:400,
        height:300,
        layout:'form',
        bodyStyle:'padding:10px',
        labelWidth:70,
        defaults:{anchor:'100%'},
        items:[{
            xtype:'iconcombo',
            fieldLabel:'IconCombo',
            store: new Ext.data.SimpleStore({
                    fields: ['countryCode', 'countryName', 'countryFlag'],
                    data: [
                        ['US', 'United States', 'ux-flag-us'],
                        ['DE', 'Germany', 'ux-flag-de'],
                        ['FR', 'France', 'ux-flag-fr']
                    ]
            }),
            valueField: 'countryCode',
            displayField: 'countryName',
            iconClsField: 'countryFlag',
            triggerAction: 'all',
            mode: 'local'
        }]
    });
    win.show();
});
    &lt;/script&gt;
    &lt;title&gt;Icon Combo Ext 2.0 Extension Class Example&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Этот файл помимо html разметки содержит функцию фасад &#8211; <strong>onReady</strong>, которая создает окно с формой, а на ней единственный элемент наш iconcombo. Будьте внимательны, в этом примере реальной формы не создается (тега &lt;form&gt; нет). Хранилище (<strong>store</strong>) iconcombo содержит уже заполненые данные для тестирования.</p>
<p>Вам необходимо изменить пути к файлам ExtJS, если он установлен в другом месте.</p>
<p>Вам, возможно, также понадобится поменять пути к изображениям флагов.</p>
<h2>Ext.ux.IconCombo.js</h2>
<pre class="brush: jscript;">
// vim: ts=4:sw=4:nu:fdc=2:nospell
/**
  * Ext.ux.IconCombo Extension Class for Ext 2.x Library
  *
  * @author  Ing. Jozef Sakalos
  * @version $Id: Ext.ux.IconCombo.js 617 2007-12-20 11:29:56Z jozo $
  *
  * @class Ext.ux.IconCombo
  * @extends Ext.form.ComboBox
  */
Ext.ux.IconCombo = Ext.extend(Ext.form.ComboBox, {
    initComponent:function() {

        // call parent initComponent
        Ext.ux.IconCombo.superclass.initComponent.call(this);

    } // end of function initComponent
});

// register xtype
Ext.reg('iconcombo', Ext.ux.IconCombo);

// end of file
</pre>
<p>Первый шаг в расширении класса, это создание дополнения, которое не изменяет функциональности родительского класса. Таким образом мы можем быть уверены, что родительский класс отлично работает, и добавленный нами функционал не затронет его работу.</p>
<p>Javascript файл выше делает именно это.</p>
<h2>Теория.</h2>
<p>Чтобы расширить класс в ExtJS мы не должны создавать функцию-конструктор. Нам просто нужно присвоить значение возвращаемое функцией <strong>Ext.extend</strong> при ее вызове в нашем пространстве имен. <strong>Ext.extend</strong> получает в качестве аргументов родительский класс и конфиг (функционал расширения) в качестве второго аргумента, и возвращает наш класс-раширение.</p>
<p>Все что мы раньше делали в конструкторе в старых версиях Ext 1.x, теперь делается в методе <strong>initComponent</strong>, который мы перезаписываем в родительском классе. <strong>initComponent </strong>это метод-конструктор родительского класса.</p>
<p>Тем не менее метод <strong>initComponent </strong>родительского класса содержит полезный код, который должен быть выполнен. Вы можете посмотреть как мы вызываем метод <strong>initComponent </strong>родительского класса в приведенном выше коде. Модель вызова метода родителя, одинакова для все функции, которые мы переопределяем в классе.</p>
<p>Регистрации <strong>xtype </strong>для нашего расширения не является обязательной, но это очень удобно, вы можете вызывать расширение просто набрав несколько символов имени его <strong>xtype</strong>. То есть точно также, как показано в этом примере.</p>
<h2>Приступим.</h2>
<p>Пока все хорошо. Теперь если открыть <strong>iconcombo.html</strong>, вы должны увидеть стандартный <strong>combobox</strong> с тремя значениями и выбранной Германией. Пока конечно же никаких иконок.</p>
<p>Теперь пришло время поработать. Добавьте следующие строки в <strong>Ext.ux.IconCombo.js </strong>перед вызовом родительского метода <strong>initComponent</strong>:</p>
<pre class="brush: jscript;">
Ext.apply(this, {
            tpl:  '&lt;tpl for=&quot;.&quot;&gt;'
                + '&lt;divst0&quot;&gt;'{' + this.iconClsField + '}&quot;&gt;'
                + '{' + this.displayField + '}'
                + '&lt;/div&gt;&lt;/tpl&gt;'
        });
</pre>
<p>В этом коде мы переопределяем стандартные элементы <strong>combobox </strong>нашими, которые будут использовать css класс <strong>iconClsField.</strong></p>
<p>Отлично, готовы протестировать ? Обновите страницу, круто да ?</p>
<p>Замечательно у нас красивые значки при открытии списка, но мы также хотим видеть флаг, когда <strong>combobox </strong>закрыт, не так ли ?</p>
<p>Добавьте следующий код после окончания кода метода <strong>initComponent</strong>:</p>
<pre class="brush: jscript;">
onRender:function(ct, position) {
        // call parent onRender
        Ext.ux.IconCombo.superclass.onRender.call(this, ct, position);

        // adjust styles
        this.wrap.applyStyles({position:'relative'});
        this.el.addClass('ux-icon-combo-input');

        // add div for icon
        this.icon = Ext.DomHelper.append(this.el.up('div.x-form-field-wrap'), {
            tag: 'div', style:'position:absolute'
        });
    }, // end of function onRender

    setIconCls:function() {
        var rec = this.store.query(this.valueField, this.getValue()).itemAt(0);
        if(rec) {
            this.icon.className = 'ux-icon-combo-icon ' + rec.get(this.iconClsField);
        }
    }, // end of function setIconCls

    setValue: function(value) {
        Ext.ux.IconCombo.superclass.setValue.call(this, value);
        this.setIconCls();
    } // end of function setValue
</pre>
<p>Вызов события <strong>onRender </strong>сначала вызывает родительский метод <strong>onRender</strong>, а потом добавляет стили и div&#8217;ы с иконками.</p>
<p>Мы также добавляем метод <strong>setIconCls </strong>и перезаписываем родительский метод <strong>setValue. </strong>Конечно мы хотим, чтобы родительский метод <strong>setValue </strong>тоже выполнился, поэтому мы сначала вызываем его, а потом выполняем наш метод <strong>setIconCls.</strong></p>
<h2>Окончание.</h2>
<p>Теперь последние испытание: перезагрузите страницы. Если вы при копировании примера не сделали ошибок вы получили новое расширение <strong>Ext.ux.IconCombo</strong>. Конечно<strong> </strong>можно еще усовершенствовать наше расширение, но это только лишь пример, как раcширять классы в ExtJS.</p>
<h2>Окончательный код.</h2>
<p>Вот полный код того, что у нас получилось:</p>
<pre class="brush: jscript;">
// vim: ts=4:sw=4:nu:fdc=2:nospell
/**
  * Ext.ux.IconCombo Extension Class for Ext 2.x Library
  *
  * @author  Ing. Jozef Sakalos
  * @version $Id: Ext.ux.IconCombo.js 617 2007-12-20 11:29:56Z jozo $
  *
  * @class Ext.ux.IconCombo
  * @extends Ext.form.ComboBox
  */
Ext.ux.IconCombo = Ext.extend(Ext.form.ComboBox, {
    initComponent:function() {

        Ext.apply(this, {
            tpl:  '&lt;tpl for=&quot;.&quot;&gt;'
                + '&lt;divst0&quot;&gt;'{' + this.iconClsField + '}&quot;&gt;'
                + '{' + this.displayField + '}'
                + '&lt;/div&gt;&lt;/tpl&gt;'
        });

        // call parent initComponent
        Ext.ux.IconCombo.superclass.initComponent.call(this);

    }, // end of function initComponent

    onRender:function(ct, position) {
        // call parent onRender
        Ext.ux.IconCombo.superclass.onRender.call(this, ct, position);

        // adjust styles
        this.wrap.applyStyles({position:'relative'});
        this.el.addClass('ux-icon-combo-input');

        // add div for icon
        this.icon = Ext.DomHelper.append(this.el.up('div.x-form-field-wrap'), {
            tag: 'div', style:'position:absolute'
        });
    }, // end of function onRender

    setIconCls:function() {
        var rec = this.store.query(this.valueField, this.getValue()).itemAt(0);
        if(rec) {
            this.icon.className = 'ux-icon-combo-icon ' + rec.get(this.iconClsField);
        }
    }, // end of function setIconCls

    setValue: function(value) {
        Ext.ux.IconCombo.superclass.setValue.call(this, value);
        this.setIconCls();
    } // end of function setValue
});

// register xtype
Ext.reg('iconcombo', Ext.ux.IconCombo);

// end of file
</pre>
<p><em>Источник: <a href="http://www.extjs.com/learn/Tutorial:Extending_Ext2_Class" target="_blank">http://www.extjs.com/learn/Tutorial:Extending_Ext2_Class.</a></em></p>
<img src="http://xo66ut.ru/?ak_action=api_record_view&id=275&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://xo66ut.ru/archives/275/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Что такое scope и createDelegate() в ExtJS</title>
		<link>http://xo66ut.ru/archives/299</link>
		<comments>http://xo66ut.ru/archives/299#comments</comments>
		<pubDate>Tue, 20 Apr 2010 15:51:39 +0000</pubDate>
		<dc:creator>Xo66uT</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Application]]></category>

		<guid isPermaLink="false">http://xo66ut.ru/?p=299</guid>
		<description><![CDATA[Часто возникает ситуация при создании монолитного класса, когда необходимо внутри функции вызвать методы или свойства, главного класса.  При этом область видимости удобного для этих целей this весьма ограничена. В ExtJS для такой задачи имеется очень удобное решение.
Предположим у нас есть класс object1:

var object1 = {
    property1 : 'Свойство 1',
    [...]]]></description>
			<content:encoded><![CDATA[<p>Часто возникает ситуация при создании монолитного класса, когда необходимо внутри функции вызвать методы или свойства, главного класса.  При этом область видимости удобного для этих целей <em>this </em>весьма ограничена. В ExtJS для такой задачи имеется очень удобное решение.<span id="more-299"></span></p>
<p>Предположим у нас есть класс <em>object1</em>:</p>
<pre class="brush: jscript;">
var object1 = {
    property1 : 'Свойство 1',
    method1 : function() {
        alert(this.property1);
    }
}
</pre>
<p>При вызове <strong>object1.method1(); </strong>У нас выпадет alert с текстом: &#8220;Свойство 1&#8243;.</p>
<p>Создадим другой класс, назовем его <em>object2</em></p>
<pre class="brush: jscript;">
var object2 = {
    property1 : 'Свойство object2',
}
</pre>
<p>Теперь попробуем выполнить следующий код: <strong>object1.method1.call(</strong>object2<strong>); </strong>У нас выпадет <em>alert </em>с текстом: &#8220;Свойство object2&#8243;. Почему так получилось ? Мы указали функции при вызове &#8220;<em>scope</em>&#8221; объект, то есть объект, который функция присвоила <em>this</em>, как будто бы мы написали в теле функции <em>this </em>= <em>object2</em>; поэтому текущим у нас оказался объект <em>object2</em>, а не <em>object1.</em></p>
<p>Когда у нас нет возможности вызывать метод call, это например, происходит при создании новой функции, в ExtJS есть специальный метод <em>createDelegate, </em>который так же принимает в качестве аргумента &#8220;scope&#8221; объект, в данном случае <em>object2</em>:</p>
<pre class="brush: jscript;">
var newFunction = object1.method1.createDelegate(object2);
</pre>
<p>Теперь если мы вызовем нашу созданную функцию<strong> newFunction();</strong> то мы также получим <em>alert c </em>текстом: &#8220;Свойство object2&#8243;.</p>
<p>Иногда &#8220;<em>scope</em>&#8221; объект удобно указывать через свойство объекта. Допустим у нас есть метод в классе <em>AjaxObject</em>, представляющий из себя ajax запрос, и есть свойство класса <em>property1</em>:</p>
<pre class="brush: jscript;">
var AjaxObject = {
    property1: 'Свойство 1',
    scope: this,
    sendAxaj: function() {
        Ext.Ajax.request({
            url: '/api.php/' ,
            method: 'GET',
            success: this.ajaxSuccess,
            params: post,
            scope: this
        });
    },
    ajaxSuccess: function(response) {
        alert(this.property1);
    }
}
</pre>
<p>Для того, чтобы мы могли каждый раз использовать методы и свойства главного класса <em>AjaxObject</em>, мы прописываем объектам свойство <em>scope: this. </em>Это в первом случае позволяет нам легко использовать метод обратившись через <em>this.ajaxSuccess</em>. А во втором случае, в <em>callback </em>функции использовать свойство главного класса <em>AjaxObject this.property1</em>.</p>
<p><em>Scope </em>и <em>createDelegate()</em> является незаменимой вещью при построении больших приложений методом <a href="http://xo66ut.ru/archives/253" target="_self">пред настроенных классов</a>.</p>
<img src="http://xo66ut.ru/?ak_action=api_record_view&id=299&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://xo66ut.ru/archives/299/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Написание больших приложений на ExtJS (Часть3)</title>
		<link>http://xo66ut.ru/archives/288</link>
		<comments>http://xo66ut.ru/archives/288#comments</comments>
		<pubDate>Sat, 27 Mar 2010 09:35:26 +0000</pubDate>
		<dc:creator>Xo66uT</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Перевод]]></category>
		<category><![CDATA[Application]]></category>

		<guid isPermaLink="false">http://xo66ut.ru/?p=288</guid>
		<description><![CDATA[
Важно.
Если вы этого еще не сделали, обязательно прочитайте первую часть и вторую часть этой статьи. Без этого будет очень трудно объяснить (или даже невозможно), а для вас понять, что написано в этой части.
Вступление.
Помогая на форуме, и читая код людей, которые делали ошибки при наследовании ExtJS классов, я обратил внимание на ошибки, которые пользователи обычно делают. [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" style="border: 0pt none; margin-right: 15px;" src="http://xo66ut.files.wordpress.com/2010/03/extconicon3.png" alt="" width="128" height="128" align="left" /></p>
<h2>Важно.</h2>
<p>Если вы этого еще не сделали, обязательно прочитайте <a href="http://xo66ut.ru/archives/253">первую часть</a> и <a href="http://xo66ut.ru/archives/277" target="_self">вторую часть</a> этой статьи. Без этого будет очень трудно объяснить (или даже невозможно), а для вас понять, что написано в этой части.</p>
<h2>Вступление.</h2>
<p>Помогая на форуме, и читая код людей, которые делали ошибки при наследовании ExtJS классов, я обратил внимание на ошибки, которые пользователи обычно делают. Поэтому я решил написать эту статью, в которой буду собирать эти ошибки, и объяснять как их решать. Я имею ввиду что я не буду создавать больше частей этой статьи, а буду добавлять найденные ошибки сюда, вместо того чтобы бесконечно создавать части 4, 5 и т.д.<span id="more-288"></span></p>
<h2>Наиболее распространенными источниками ошибок являются:</h2>
<ol>
<li>Ненужное наследование.</li>
<li>Добавление объектов к прототипу.</li>
<li>Жесткая привязка к id.</li>
</ol>
<h2>Ненужное наследование.</h2>
<p>Основными причинами наследования являются:</p>
<ol>
<li>Повторное использование.</li>
<li>Добавление функциональности.</li>
<li>И то и другое.</li>
</ol>
<p>поэтому мы наследуем, если нам необходимо создать компонент для многократного использования <strong>или</strong> нам нужно добавить новый функционал классу (новые методы) или и то и другое. Если мы говорим о повторном использовании, наследование может быть простым:</p>
<pre class="brush: jscript;">

MyPortlet = Ext.extend(Ext.Panel, {

anchor:'100%'

,draggable:true

,defaultType:'mygraph'

});
</pre>
<p>Вы видите что получается ? Мы будем использовать класс MyPortlet много раз, поэтому вместо того что писать каждый раз в приложении в 10000 строк эти строчки, мы просто 100 раз вызовем пред настроенный объект и сэкономим 297 строк кода.</p>
<p>Другая польза этого метода состоит в том, что если мы хотим изменить тип с ‘mygraph’ на ‘mygraph_new’, нам надо лишь поменять код в классе, который мы используем, это избавит нас от поиска и замены это же параметра в 100 мест кода.</p>
<p>(Ну 100 раз это конечно преувеличение, но экономия все равно будет).</p>
<p>Если говорить о добавлении нового функционала, то вот простой пример:</p>
<pre class="brush: jscript;">

MyPanel = Ext.extend(Ext.Panel, {

onRender:function() {

MyPanel.superclass.onRender.apply(this, arguments);

alert('Rendered');

}

});
</pre>
<p>Здесь мы добавили новую логику к Ext.Panel, теперь у нашего класса больше возможностей, чем раньше.</p>
<p><strong>Во всех других случаях использовать наследование нет необходимости.</strong></p>
<h2>Добавление объектов к прототипу.</h2>
<p>Для начала выполним следующий код:</p>
<pre class="brush: jscript;">
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;ext/resources/css/ext-all.css&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;ext/adapter/ext/ext-base.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;ext/ext-all-debug.js&quot;&gt;&lt;/script&gt;
&lt;title id=&quot;page-title&quot;&gt;Extending Error: Object in prototype&lt;/title&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';
Ext.onReady(function() {
MyPanel = Ext.extend(Ext.Panel, {
layout:'fit'
,panelConfig: {
bodyBg:'red'
}

,initComponent:function() {
var config = {
bodyStyle:'background-color:' + this.panelConfig.bodyBg
}; // eo config object

// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));

MyPanel.superclass.initComponent.apply(this, arguments);
} // eo function initComponent

,applyBackground:function(color) {
this.panelConfig.bodyBg = color;
this.body.applyStyles({'background-color':color});
} // eo function applyBackground

}); // eo extend

var p1 = new MyPanel({
title:'Panel with Blue Background'
,renderTo:Ext.getBody()
,width:240
,height:160
});

p1.applyBackground('blue');

var p2 = new MyPanel({
title:'Panel with Red Background'
,renderTo:Ext.getBody()
,width:240
,height:160
});

});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Чего мы ожидаем ? Это написано в title панелей: Верхняя панель (p1) должна быть с синим бэкграундом, потому что мы установили ей этот параметр после того как создали объект. А у нижней панели (p2) должен быть красный бэкграунд, потому что он стоит по умолчанию в классе MyPanel.</p>
<p><strong>Но она получается тоже голубой!!! Почему ?</strong> Причина проста panelConfig  это объект, который создается при определении класса и он добавляется к прототипу MyPanel. Объекты (массивы тоже) доступны по ссылке, получается что p1 и p2 используют один и тот же panelConfig. Устанавливая свойство bodyBg в методе applyBackground мы изменяем panelConfig. Поэтому мы создаем панель p2 с таким же голубым цветом.</p>
<p>Здесь вы сразу увидели ошибку, но устранение этой ошибки может занят у вас недели в реальных приложениях. Представьте например, что у вас прототип класса store.</p>
<h2>Жесткая привязка к id.</h2>
<p>Очень простой, но смертельной ошибкой является жесткая привязка наследуемого класса или его items, tollbars, buttons объектов к определенному id. Если мы жестко привязываемся к определенному id, мы не сможем создать несколько экземпляров нашего класса, ведь так ?</p>
<h2>Вместо заключения.</h2>
<p>Это пока все, но если я найду еще какие-либо ошибки, я обязательно добавлю их выше.</p>
<p>Оставайтесь с нами!</p>
<p><em>Источник:</em> <a href="http://blog.extjs.eu/know-how/writing-a-big-application-in-ext-part-3/" target="_blank">http://blog.extjs.eu/know-how/writing-a-big-application-in-ext-part-3/</a></p>
<p>Не забудьте прочитать <a href="http://xo66ut.ru/archives/253" target="_self">первую</a> и <a href="http://xo66ut.ru/archives/277" target="_self">вторую</a> часть этой статьи.</p>
<img src="http://xo66ut.ru/?ak_action=api_record_view&id=288&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://xo66ut.ru/archives/288/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Написание больших приложений на ExtJS (Часть2)</title>
		<link>http://xo66ut.ru/archives/277</link>
		<comments>http://xo66ut.ru/archives/277#comments</comments>
		<pubDate>Fri, 26 Mar 2010 08:11:33 +0000</pubDate>
		<dc:creator>Xo66uT</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Перевод]]></category>
		<category><![CDATA[Application]]></category>

		<guid isPermaLink="false">http://xo66ut.ru/?p=277</guid>
		<description><![CDATA[
Важно.
Если вы этого еще не сделали, обязательно прочитайте первую часть этой статьи. Без этого будет очень трудно объяснить (или даже невозможно), а для вас понять, что написано в этой части.
Вступление.
Прошел уже практически год, с того момента, как я опубликовал первую часть моей статьи. Я успешно использую концепцию пред настроенных классов, чтобы писать реально большие приложения [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" style="border: 0pt none; margin-right: 15px;" src="http://xo66ut.files.wordpress.com/2010/03/extconicon2.png" alt="" width="128" height="128" align="left" /></p>
<h2>Важно.</h2>
<p>Если вы этого еще не сделали, обязательно прочитайте <a href="http://xo66ut.ru/archives/253">первую часть</a> этой статьи. Без этого будет очень трудно объяснить (или даже невозможно), а для вас понять, что написано в этой части.</p>
<h2>Вступление.</h2>
<p>Прошел уже практически год, с того момента, как я опубликовал первую часть моей статьи. Я успешно использую концепцию пред настроенных классов, чтобы писать реально большие приложения (~150 .js файлов ~60000 строк кода, не считая серверного кода и .css файлов). Приложение полностью модульное, каждый класс это отдельный файл, словом мой способ доказал что он упрощает разработку, организацию кода и отладку.</p>
<p>К сожалению, не все было хорошо у других, кто использовал мой подход, они сталкивались с различными проблемами и Ext Support Team обрабатывали их проблемы и просьбы о помощи. Все это привело в к тому, что мой подход стали называть &#8220;абсолютная мерзость&#8221; и было сказано, что &#8220;это создает проблемы&#8221;.</p>
<p><em>Примечание: Как быстрые автомобили сами по себе не приводят к несчастным случаям, хотя тот кто ездит медленно, часто делает это на быстрых машинах, сам способ не может быть настоящей причиной проблем, а вот его применение может.</em></p>
<p>В любом случае, есть какая-то нелогичность, что я могу использовать данный подход, а кто-то нет.</p>
<p>Так я стал смотреть глубже в причину ошибок и выделил некоторые из них с которыми пользователи могут столкнуться при разработке. Я также буду писать на тему &#8220;делать&#8221; или &#8220;не делать&#8221; и когда надо использовать пред настроенные классы, а когда нет. Я не буду сравнивать мой метод с другими (Метод Фабричных функций, прямой метод, загрузка по требованию и другие), потому что 1) я их не использую и 2) я не хочу превратить эту статью в очередной холивар между пользователями Linux и Windows.</p>
<p>Это в полной мере зависит от вас какой способ вы выберете. Однако, если вы выберете мой способ, то следуйте правилам, которые я хочу изложить.<span id="more-277"></span></p>
<h2>Наиболее распространенные источники ошибок.</h2>
<ul>
<li>Бездумный копи-паст</li>
<li>Расширение класса базирующегося не на <span id="result_box" class="medium_text"><span style="background-color: #ffffff;" title="* Extending a non-Ext.Component class">Ext.Component</span></span></li>
<li><span id="result_box" class="medium_text"><span style="background-color: #ffffff;" title="* Extending a non-Ext.Component class">Не вызываются родительские методы</span></span></li>
<li><span id="result_box" class="medium_text"><span style="background-color: #ffffff;" title="* Extending a non-Ext.Component class">initialConfig</span></span></li>
<li><span id="result_box" class="medium_text"><span style="background-color: #ffffff;" title="* Extending a non-Ext.Component class">Слушатели событий<br />
</span></span></li>
</ul>
<h2>Бездумные копи-пастеры.</h2>
<p>Вы знаете этих людей ? Они пишут на форуме:</p>
<p>Мне нужно перетащить текст с Tree на Grid, дай pliz полный рабочий codez.</p>
<p>И если кто-то и альтруистов пишет им фрагмент его &#8220;codez&#8221;, чтобы помочь ему, то в ответ будет:</p>
<p>Твой код не работает, помоги мне, мой менеджер хочет чтобы все работало.</p>
<p>Вы ведите, что происходит, такой &#8220;разработчик&#8221; , получив код на форуме скопипастил его, без задней мысли, не понимая, что этот код вообще делает, может даже он не изменил URL для своего сервера, и конечно же все не работает.</p>
<p>Это конечно крайности (но они случаются не столь редко, как вы могли подумать), тем не менее бездумный копи-паст может перевести лишь к разочарованиям.</p>
<p>Я не против копи-паста в целом, с помощью него можно сэкономить уйму времени, я тоже иногда это делают, но я против бездумного или не правильного понимания и это касается не только программирования, но и реальной жизни.</p>
<p><em>Правило: </em><strong>Делайте копи-паст, но всегда с пониманием того, что делает код.</strong></p>
<p><strong>Расширение класса основанного не на Ext.Component.</strong></p>
<p>Если класс ExtJS не наследуется от Ext.Component, функция initComponent  (Инициализатор компонента), не вызывается, таким образом код, который вы напишете в этой функции никогда не будет выполнен. Вот фрагмент кода из конструктора класса Ext.Component:</p>
<pre class="brush: jscript;">
this.getId();
Ext.ComponentMgr.register(this);
Ext.Component.superclass.constructor.call(this);

if(this.baseAction){
this.baseAction.addComponent(this);
}

this.initComponent();
</pre>
<p>ExtJS классы которые не наследуются от Ext.Component не имею строчки this.initComponent(); в своем исходном коде.</p>
<p><em>Правило: </em><strong>Всегда проверяйте, наследуется ли класс, который вы хотите пред настроить, от класса Ext.Component. Вы должны использовать другой подход, если это не так.</strong></p>
<h2>Не вызываются родительские методы.</h2>
<p>Часто случается так, что вы не только добавляете несколько методов в наследуемый класс, но так же вы изменяете уже существующие методы. initComponent &#8211; первый пример,  onRender, afterLayout, и другие (но и не только они) часто переопределяемые методы.</p>
<p>Эти методы уже есть в вашем классе и в родительском, от которого вы его наследуете, поэтому, если вы забудете строчки:</p>
<pre class="brush: jscript;">
// in initComponent override
YourExtension.superclass.initComponent.apply(this, arguments);

// or in onRender override
YourExtension.superclass.onRender.apply(this, arguments);

// or in afterLayout override
YourExtension.superclass.afterLayout.apply(this, arguments);
</pre>
<p>ваш класс работать не будет.</p>
<p><em>Правило:</em> <strong>Никогда не забывайте вызвать родительский метод, если вы уверены в том, что вы делаете.</strong></p>
<h2>initialConfig.</h2>
<p>Конструктор класса Ext.Component сохраняет переданный ему конфиг, как свойство initialConfig:</p>
<pre class="brush: jscript;">
/**
* This Component's initial configuration specification. Read-only.
* @type Object
* @property initialConfig
*/
this.initialConfig = config;

Ext.apply(this, config);
this.addEvents(/* abbreviated for clarity */);
this.getId();
Ext.ComponentMgr.register(this);
Ext.Component.superclass.constructor.call(this);

if(this.baseAction){
this.baseAction.addComponent(this);
}

this.initComponent();
</pre>
<p>Вы видите, что происходит ? Конструктор сохраняет initialConfig до того как выполняется метод initComponent. Таким образом весь ваш конфиг написанный в методе initComponent не сохраняется. Я не заметил этого в первой версии моих шаблонов и примеров, главным образом потому, что есть всего лишь несколько классов, которые используются свойство initialConfig и даже в этих классах вызов initComponent не правильным способом, вызывает ошибку крайне редко. Следующие классы используют свойство initialConfig:</p>
<ul>
<li>AnchorLayout</li>
<li>BorderLayout</li>
<li>Action</li>
<li>GridPanel</li>
<li> Tip</li>
<li>Combo</li>
<li>Form</li>
</ul>
<p>Сейчас я обновил все мои примеры, расширения, шаблоны и основной сайт, чтобы включить в него этот &#8220;магический&#8221; шаблон:</p>
<pre class="brush: jscript;">
// create config
var config = {
// put your config here
}; // eo config object

// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));

// call parent
YourExtension.superclass.initComponent.apply(this, arguments);
</pre>
<p><em>Правило:</em> <strong>Убедитесь, что ваш класс-потомок сохраняет свойство initialConfig.</strong></p>
<h2>Слушатели событий.</h2>
<p>Если вы попытаетесь установить обработчики событий, через свойства в конфиге, они не будут работать. Почему ? Ответ опять находится в порядке выполнения действий конструктора Ext.Component:</p>
<pre class="brush: jscript;">
Ext.Component.superclass.constructor.call(this);

if(this.baseAction){
this.baseAction.addComponent(this);
}

this.initComponent();
</pre>
<p>Как вы видите конструктор вызывает своего родителя, который является классом Ext.util.Observable до initComponent, а Ext.util.Observable конструктор выполняет:</p>
<pre class="brush: jscript;">
Ext.util.Observable = function(){
if(this.listeners){
this.on(this.listeners);
delete this.listeners;
}
};
</pre>
<p>Таким образом любые слушатели событий в initComponent игнорируются.</p>
<p>Существует простой способ решить эту проблему. Положите метод конструктора класса в ваш класс потомок:</p>
<pre class="brush: jscript;">
constructor:function(config) {
// parent constructor call pre-processing - configure listeners here
config = config || {};
config.listeners = config.listeners || {};
Ext.applyIf(config.listeners, {
// add listeners config here
});

// call parent constructor
AnExtension.superclass.constructor.call(this, config);

// parent constructor call post-processing

} // eo function constructor
</pre>
<p>и определяйте слушателей событий в нем.</p>
<p><em>Правило:</em> <strong>Назначайте слушателей событий в методе-конструкторе.</strong></p>
<p><strong>Заключение.</strong></p>
<p>Если вы решите использовать мой способ написания больших приложений на ExtJS, следуйте следующим правилам:</p>
<ol>
<li>Применяйте копи-паст всегда с полным пониманием того, что делает код.</li>
<li>Всегда проверяйте наследуется ли класс который вы хотите пред настроить от Ext.Component. Вы должны использовать другой подход, если это не так.</li>
<li>Никогда не забывайте вызвать родительский метод, если вы уверены в том, что делаете.</li>
<li>Убедитесь что ваш класс сохраняет свойство initialConfig.</li>
<li>Назначайте слушателей событий в методе-конструкторе.</li>
</ol>
<p>Удачного наследования!</p>
<p><em>Источник:</em> <a href="http://blog.extjs.eu/know-how/writing-a-big-application-in-ext-part-2/" target="_blank">http://blog.extjs.eu/know-how/writing-a-big-application-in-ext-part-2/</a></p>
<img src="http://xo66ut.ru/?ak_action=api_record_view&id=277&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://xo66ut.ru/archives/277/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Написание больших приложений на ExtJS (Часть1)</title>
		<link>http://xo66ut.ru/archives/253</link>
		<comments>http://xo66ut.ru/archives/253#comments</comments>
		<pubDate>Wed, 24 Mar 2010 09:41:48 +0000</pubDate>
		<dc:creator>Xo66uT</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Перевод]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[xtype]]></category>

		<guid isPermaLink="false">http://xo66ut.ru/?p=253</guid>
		<description><![CDATA[
Предисловие
Я решил написать эту статью для тех пользователей Ext 2.x, которые уже выросли из приложений состоящих из одной HTML страницы со встроенным скриптом, который создает одно простое окно или форму, для тех, кто уже решили, что Ext это их выбор и для тех, кто борется со слишком большими файлами, где трудно что-то найти и тех, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" style="border: 0pt none; margin-right: 15px;" src="http://xo66ut.files.wordpress.com/2010/03/extconicon.png" alt="" width="128" height="128" align="left" /></p>
<h2>Предисловие</h2>
<p>Я решил написать эту статью для тех пользователей Ext 2.x, которые уже выросли из приложений состоящих из одной HTML страницы со встроенным скриптом, который создает одно простое окно или форму, для тех, кто уже решили, что Ext это их выбор и для тех, кто борется со слишком большими файлами, где трудно что-то найти и тех, кто чувствует, что их приложения требуют структуры.</p>
<p>Число различных подходов к решению этой проблемы равно количеству людей, которые его реализовали. Принцип, который я хочу описать ниже не является истиной в последней инстанции.</p>
<p>Я только хочу сказать, что мой подход, позволяет легко структурировать и писать красивый код. Он &#8220;реально работает&#8221;!<span id="more-253"></span></p>
<h2>Что можно назвать большим приложением ?</h2>
<p>Если у вас есть Viewport с BorderLayout, grid и формы &#8211; все в одном файле, это конечно, небольшое приложение. А вот если у вас десятки окон с формами, гридами и все это в 10 файлах, это уже не маленькое приложение, правда ?</p>
<p>(У немцев есть забавное выражение Jein, которое является производным от Ja = Да и Nein = Нет )</p>
<p>Ответ на вопрос поставленный выше это Jein (Прим. переводчика:  Русское Да-нет наверное тоже является эквивалентом этого немецкого слова). Нет однозначного ответа, когда приложение становится большим, оно становится большим, когда вы считаете, что оно стало большим. Этот момент обычно наступает, когда вы уже не можете ориентироваться в ваших файлах, когда вы перестаете понимать как ваши компоненты в приложении соотносятся друг с другом. Нужно также представлять что будет, если с вашим кодом начнет работать программист в 2 -3 раза менее опытный чем вы.</p>
<p>Мы можем с уверенностью сказать, что каждое маленькое приложение лучше сразу оформлять как большое, потому что оно очень быстро может стать большим за счет добавления нового функционала и функций, новых CSS стилей и т.д.</p>
<p>Самое лучше &#8211; начинать писать приложение со словами: &#8220;Я начинаю писать большое приложение!&#8221;.</p>
<h2>Файлы и папки.</h2>
<p>Это необходимо организовать в первую очередь. Нужно всегда начинать с ServerRoot директории настроенной в Apache или каком-нибудь другом HTTP сервере, все описанные далее папки идут относительно нее.</p>
<p>. /css(опционально ссылка)</p>
<p>. /ext (ссылка)</p>
<p>. /img (ссылка)</p>
<p>. /js</p>
<p>index.html</p>
<p>Ссылка в приведенной выше структуре означает мягкую ссылку, указывающую на реальный каталог, где хранятся файлы. Преимущество заключается в том, что вы, например, скачиваете новую версию Ext, сохраняете на нее ссылку, тестируете ваше приложение с новой версией фреймворка и если появляются какие-то ошибки просто меняете ссылку на старую версию Ext.</p>
<p>* css будет содержать все ваши таблицы стилей. Если у вас есть глобальные таблицы стилей с фирменными цветами и шрифтами можно создать в CSS каталоге ссылку.</p>
<p>* ext ссылки на дерево ExtJS библиотек разных версий.</p>
<p>* img ссылки на изображения. Он может содержать также подкаталоги.</p>
<p>* js будет содержать все скрипты вашего приложения.</p>
<p>* index.html файл HTML, который является отправной точкой вашего приложения. Вы можете назвать его как хотите, и вам может понадобиться еще несколько файлов, например, для авторизации.</p>
<p>* По желанию, вы можете создать директорию или ссылку на ваши серверные скрипты (у меня есть. / classes).</p>
<p>(<em>Прим.Переводчика: ссылки для Linux</em>).</p>
<h2>index.html</h2>
<p>Примерное минимальное содержимое файла index.html выглядит следующим образом:</p>
<pre class="brush: xml;">

&lt;html&gt;

&lt;head&gt;

&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;

&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;./ext/resources/css/ext-all.css&quot;&gt;

&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;./css/application.css&quot;&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;./ext/adapter/ext/ext-base.js&quot;&gt;&lt;/script&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;./ext/ext-all-debug.js&quot;&gt;&lt;/script&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;./application.js&quot;&gt;&lt;/script&gt;

&lt;title&gt;A Big Application&lt;/title&gt;

&lt;/head&gt;

&lt;body&gt;&lt;/body&gt;

&lt;/html&gt;
</pre>
<h2>application.js</h2>
<p>Нам нужен файл в котором будет размещена функция <span id="result_box" class="medium_text"><span style="background-color: #ffffff;" title="We need a file where the onReady function  will be placed; let's call it application.js.">onReady, </span></span><span id="result_box" class="medium_text"><span style="background-color: #ffffff;" title="We need a file where the onReady function  will be placed; let's call it application.js.">давайте назовем его  application.js. </span><span style="background-color: #ffffff;" title="Minimum content is:">Минимальное содержание выглядит так:</span></span></p>
<pre class="brush: jscript;">

/**

* An Application

*

* @author    Ing. Jozef Sakáloš

* @copyright (c) 2008, by Ing. Jozef Sakáloš

* @date      2. April 2008

* @version   $Id$

*

* @license application.js is licensed under the terms of the Open Source

* LGPL 3.0 license. Commercial use is permitted to the extent that the

* code/component(s) do NOT become part of another Open Source or Commercially

* licensed development library or toolkit without explicit permission.

*

* License details: http://www.gnu.org/licenses/lgpl.html

*/

/*global Ext, Application */

Ext.BLANK_IMAGE_URL = './ext/resources/images/default/s.gif';

Ext.ns('Application');

// основная точка входа нашего приложения

Ext.onReady(function() {

Ext.QuickTips.init();

Здесь будет код вызова основного класса приложения

});

// eof
</pre>
<p>Ваш header и footer может быть различным, но уверен, вы должны установить параметр Ext.BLANK_IMAGE_URL, чтобы он указывал на картинку на локальном сервере. Это путь к 1 × 1px прозрачной картинке, которая используется Ext для пустых областей, если параметр указывает на неправильное место, у вас могут возникнуть различные проблемы &#8211; такие, как отсутствие изображения-переключателя у Combobox, либо отсутствие иконок.</p>
<p>Вам также может понадобиться создать новую глобальную переменную-объект для приложения (в данном случае это Application).</p>
<p>Вы должны быть уверены, что Ext.onReady, это начало вашего приложения &#8211; место, где вы пишете его инициализацию.</p>
<h2>css/application.css</h2>
<p>Вы будете хранить ваши css стили в этом файле. Если вам нужно всего лишь несколько правил, то может показаться, что нет необходимости создавать отдельный файл для них, и что это хорошая идея положить их в тег &lt;style&gt; в заголовке.</p>
<p>Это не так, помните, что вы пишете большое приложение, так что все должно быть на своем месте. Если вы поместите стили в header, страницы рано или поздно, у вас появится проблемы с ними. И вы не будете знать где они находятся.</p>
<h2>Как делать Неправильно!</h2>
<p>Что мы обычно делаем когда узнали основы, правильно, начинаем писать код:</p>
<pre class="brush: jscript;">
var vp = new Ext.Viewport({
layout:'border'
,items:[
new Ext.grid.GridPanel({
store:new Ext.data.Store({
proxy:new Ext.data.HttpProxy({ ...
</pre>
<p>Подождите минутку. Так мы очень скоро получим более 10000 строк в нашем файле application.js, а это то, что мы хотим в самую последнюю очередь. Очевидно мы что-то пропустили, если мы создаем такой большой файл, почему бы нам вообще не написать все в index.html.</p>
<h2>Правильное решение - разделить все!</h2>
<p>Даже самые сложные элементы всегда состоят из небольших систем, которые в свою очередь состоят из маленьких элементов. Ваше будущее большое приложение не исключение. Теперь настало время определить что это за составные части  и компоненты, и найти отношения между ними.</p>
<p>Итак, сядьте, подумайте, нарисуйте эскиз, составьте список, в конце концов вы будете знать из чего состоит ваше приложение.</p>
<h2>Предварительно настроенные классы.</h2>
<p>Итак, сейчас, когда вы определились со структурой вашего приложения, вы начнете писать первый из компонентов. Но каким образом ? Лучше решение - это расширить классы компонентов ExtJS, добавить в них конфигурационные параметры. Я называю такие объекты пред настроенными компонентами, они редко добавляют какой-то функционал в стандартный класс ExtJS, но главная цель этого - пред настройка. Например чтобы иметь преднастроенный grid, с собственномы ColumnModel, store, sorting option, editor и т.д.  делаем следующее:</p>
<pre class="brush: jscript;">
Application.PersonnelGrid = Ext.extend(Ext.grid.GridPanel, {
border:false
,initComponent:function() {
var config = {
store:new Ext.data.Store({...})
,columns:[{...}, {...}]
,plugins:[...]
,viewConfig:{forceFit:true}
,tbar:[...]
,bbar:[...]
}; // eo config object

// Применяем config
Ext.apply(this, Ext.apply(this.initialConfig, config));

Application.PersonnelGrid.superclass.initComponent.apply(this, arguments);
} // eo function initComponent

,onRender:function() {
this.store.load();

Application.PersonnelGrid.superclass.onRender.apply(this, arguments);
} // eo function onRender
});

Ext.reg('personnelgrid', Application.PersonnelGrid);
</pre>
<p>После создания преднастроенного класса мы можем его использовать следующим образом:</p>
<pre class="brush: jscript;">
var win = new Ext.Window({
title:'Personnel'
,widht:600
,height:400
,items:{xtype:'personnelgrid'}
});
win.show();
</pre>
<p>Что мы сделали ? Мы расширили класс <strong>Ext.grid.GridPanel</strong> создав новый класс <strong>Application.PersonnelGrid</strong> и мы зарегистрировали его как <strong>xtype </strong>с именем <strong>personnelgrid.</strong></p>
<p>Мы настраиваем класс GridPanel всеми необходимыми функциями, которые нужны, чтобы этот класс стал объектом PersonnelGrid. С этого момента у нас появился новый компонент, строительный блок нашего приложения, который мы можем использовать в любом месте ( в окне, в таблице, самостоятельно &#8211; отдельно от всего остального). Мы можем создать его двумя способами:</p>
<pre class="brush: jscript;">
//Напрямую через объект
var pg = new Application.PersonnelGrid();

// или используя его xtype имя
var win = new Ext.Window({
items:{xtype:'personnelgrid'}
,....

});
</pre>
<h2>Организация пред настроенных классов.</h2>
<p>Приведенный выше код не нужно помещать в функцию OnReady, поскольку он не имеет ничего общего со структурой DOM, а лишь создает новый объект JavaScript. Поэтому он может и должен быть записан в отдельный файл (js/Application.PersonnelGrid.js) и должен быть включен в заголовок index.html следующем образом:</p>
<pre class="brush: xml;">
&lt;script type=&quot;text/javascript&quot; src=&quot;./js/Application.PersonnelGrid&quot;&gt;&lt;script&gt;
</pre>
<p>Пока все хорошо, у нас практически все на своем месте, и почти все что нам необходимо в дальнейшем это писать вот такие пред настроенные классы, помещать их в каталог ./js, добавлять в index.html, и собирать приложения из этих компонентов, как мозайку из составных частей.</p>
<p>Выглядит неплохо, правда ?</p>
<p>Хотя есть еще кое что, что необходимо знать.</p>
<h2>Коммуникация между компонентами.</h2>
<p>Представьте себе, что нам нужно разместить в одном месте справа TabPanel (панель с вкладками), а слева список ссылок. Нажимая на ссылку мы будем создавать новую владку на панели справа. Куда мы должны поместить обработчик нажатия на кнопку слева или справа ? В TabPanel или в списке ссылок ?</p>
<p>Не в одном из них. Почему ? Если у нас есть предварительно настроенный класс, который создает список ссылок и поместим наш обработчик после этого кода, то он не будет знать ничего о TabPanel. В тоже время он должен использовать TabPanel.</p>
<p>Если мы поместим обработчик в TabPanel, то будет тоже самое, он не будет знать на какую именно ссылку мы нажали.</p>
<p>Единственный компонент, который знает все о существовании списка ссылок и TabPanel &#8211; это их контейнер, он может фиксировать события этих двух компонентов, только туда мы можем поместить нужный нам обработчик.</p>
<p>Итак, что мы должны делать ? Наш главный контейнер должен слушать событие от списка ссылок и должен в ответ на это событие создавать кладки в TabPanel. Компонент который описан в этом примере можно увидеть здесь <a href="http://examples.extjs.eu/?ex=compcomm">Saki’s Ext Examples.</a></p>
<h2>Production системы.</h2>
<p>Когда мы пишем таким образом большое приложение у нас в скором времени в index.html образуется множества .js вложений (у меня в одном приложении около 80, и продолжает с каждым днем расти). Это может снизить быстродействие системы.</p>
<p>Лучший способ решить эту проблему, объединить все файлы в один при публикации вашего приложения. Это лучше всего сделать с помощью программы для уменьшения и склеивания .js файлов (<em>Прим.переводчика: я использую YUI Compressor в Eclipse</em>).  Кроме того на сервере вам не нужна debug версия ExtJS, которую вы используете при разработке. В конечном итоге на сервере у вас должно получится следующее:</p>
<p>* ext-all.js<br />
* app-all.js and<br />
* application.js</p>
<h2>Заключение.</h2>
<p>Это практически все, что вам необходимо знать. Существуют специальные способы организации кода для конкретных ExtJS классов, но выше описана основная концепция, как организовывать код в больших приложениях.</p>
<p>Удачного программирования!</p>
<p><em>Источник:</em> <a href="http://blog.extjs.eu/know-how/writing-a-big-application-in-ext/" target="_blank">http://blog.extjs.eu/know-how/writing-a-big-application-in-ext/</a></p>
<p><a href="http://xo66ut.ru/archives/277" target="_self">Часть 2</a> и Часть 3.</p>
<img src="http://xo66ut.ru/?ak_action=api_record_view&id=253&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://xo66ut.ru/archives/253/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ExtJS добавление в каждую строку Ext.grid функциональной кнопки</title>
		<link>http://xo66ut.ru/archives/242</link>
		<comments>http://xo66ut.ru/archives/242#comments</comments>
		<pubDate>Tue, 23 Mar 2010 10:59:37 +0000</pubDate>
		<dc:creator>Xo66uT</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ext.grid]]></category>

		<guid isPermaLink="false">http://xo66ut.ru/?p=242</guid>
		<description><![CDATA[Не так давно начал ознакомление с замечательным Javascript Фреймворком ExtJS, главной отличительной особенностью которого является больше количество готовых UI компонентов. Компоненты по умолчанию все стилизованы, поэтому нет необходимости заниматься версткой и рисованием, только JavaScript программирование.
Теперь о задачи которая передо мной встала. Нужно было в компонент Ext.grid добавить в каждую строчку (создать колонку) кнопок при нажатии [...]]]></description>
			<content:encoded><![CDATA[<p>Не так давно начал ознакомление с замечательным Javascript Фреймворком ExtJS, главной отличительной особенностью которого является больше количество готовых UI компонентов. Компоненты по умолчанию все стилизованы, поэтому нет необходимости заниматься версткой и рисованием, только JavaScript программирование.</p>
<p>Теперь о задачи которая передо мной встала. Нужно было в компонент Ext.grid добавить в каждую строчку (создать колонку) кнопок при нажатии на которую происходит вызов окна с параметрами. Опционально можно сделать в этом поле любой объект, допустим кнопку которая удаляет текущую строку.</p>
<p><span id="more-242"></span>Создадим класс который расширит возможности Ext.grid.RowSelectionModel класса строк Ext.grid. Я назвал этот класс Ext.ux.grid.Goto</p>
<pre class="brush: jscript;">
Ext.ns('Ext.ux.grid');

Ext.ux.grid.Goto = Ext.extend(Ext.grid.RowSelectionModel, {
width: 30,
sortable: false,
dataIndex: 0, // Нужно задать полю, потому как в родителе этот параметр не может быть пустым

menuDisabled: true,
fixed: true,
id: 'deleter',

initEvents: function(){
Ext.ux.grid.Goto.superclass.initEvents.call(this);
this.grid.on('cellclick', function(grid, rowIndex, columnIndex, e){
//Проверяем, что нажали именно на нашу ячейку Ext.grid
if(columnIndex==grid.getColumnModel().getIndexById('deleter')) {
var record = grid.getStore().getAt(rowIndex);
//Получаем параметры для вызова окна, это данные из текущей строки Ext.grid
var CampaignStepID = record.get('CampaignStepID');
var SourceID = record.get('SourceID');
var StepName = record.get('CampaignStepName');
//Вызываем функцию которая создаст окно с параметрами
getCampaignStepCard(CampaignStepID, SourceID, StepName, this.desktop);
}
});
},

//Этот метод позволяет нам нарисовать  в каждой ячейке нашей колонки, что мы хотим
renderer: function(v, p, record, rowIndex){
return '&lt;div class=&quot;silk-goto&quot; type=&quot;button&quot; style=&quot;width: 16px; height: 16px;cursor:pointer;&quot;&gt;&lt;/div&gt;';
}
});
</pre>
<p>Далее нам необходимо прицепить к Ext.grid наш плагин.<br />
Создаем новый объект</p>
<pre class="brush: jscript;">
//Добавляем плагин который активирует кнопку перехода в гриде
var GotoButton = new Ext.ux.grid.Goto();

var CampaignListCm = new Ext.ux.grid.LockingColumnModel({
// specify any defaults for each column
columns:
[
{
id: 'id',
header: 'ID',
dataIndex: 'ID',
menuDisabled: false,
hideable: false,
hidden: true,
// use shorthand alias defined above
editor: new Ext.form.TextField({
allowBlank: false
})
},
{
id: 'SourceID',
header: 'SourceID',
dataIndex: 'SourceID',
menuDisabled: false,
hideable: false,
hidden: true,
// use shorthand alias defined above
editor: new Ext.form.TextField({
allowBlank: false
})
},
GotoButton //Наша дополнительная колонка
]
});
</pre>
<p>А в сам Ext.grid добавляем наш плагин как selModel</p>
<pre class="brush: jscript;">
var grid = new Ext.grid.EditorGridPanel({
id: 'CampaignSourceID',
store: CampaignSourceList,
cm: CampaignListCm,
selModel: GotoButton,
stripeRows: true,
columnLines:true,
region: 'center'
});
</pre>
<p>Смотрим на полученный результат</p>
<div class="wp-caption alignnone" style="width: 219px"><img src="http://xo66ut.files.wordpress.com/2010/03/gridbutton.jpg" alt="Special Column in Grid" width="209" height="69" /><p class="wp-caption-text">Row in Grid</p></div>
<img src="http://xo66ut.ru/?ak_action=api_record_view&id=242&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://xo66ut.ru/archives/242/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

