Написание больших приложений на ExtJS (Часть3)

Важно.

Если вы этого еще не сделали, обязательно прочитайте первую часть и вторую часть этой статьи. Без этого будет очень трудно объяснить (или даже невозможно), а для вас понять, что написано в этой части.

Вступление.

Помогая на форуме, и читая код людей, которые делали ошибки при наследовании ExtJS классов, я обратил внимание на ошибки, которые пользователи обычно делают. Поэтому я решил написать эту статью, в которой буду собирать эти ошибки, и объяснять как их решать. Я имею ввиду что я не буду создавать больше частей этой статьи, а буду добавлять найденные ошибки сюда, вместо того чтобы бесконечно создавать части 4, 5 и т.д.

Наиболее распространенными источниками ошибок являются:

  1. Ненужное наследование.
  2. Добавление объектов к прототипу.
  3. Жесткая привязка к id.

Ненужное наследование.

Основными причинами наследования являются:

  1. Повторное использование.
  2. Добавление функциональности.
  3. И то и другое.

поэтому мы наследуем, если нам необходимо создать компонент для многократного использования или нам нужно добавить новый функционал классу (новые методы) или и то и другое. Если мы говорим о повторном использовании, наследование может быть простым:


MyPortlet = Ext.extend(Ext.Panel, {

anchor:'100%'

,draggable:true

,defaultType:'mygraph'

});

Вы видите что получается ? Мы будем использовать класс MyPortlet много раз, поэтому вместо того что писать каждый раз в приложении в 10000 строк эти строчки, мы просто 100 раз вызовем пред настроенный объект и сэкономим 297 строк кода.

Другая польза этого метода состоит в том, что если мы хотим изменить тип с ‘mygraph’ на ‘mygraph_new’, нам надо лишь поменять код в классе, который мы используем, это избавит нас от поиска и замены это же параметра в 100 мест кода.

(Ну 100 раз это конечно преувеличение, но экономия все равно будет).

Если говорить о добавлении нового функционала, то вот простой пример:


MyPanel = Ext.extend(Ext.Panel, {

onRender:function() {

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

alert('Rendered');

}

});

Здесь мы добавили новую логику к Ext.Panel, теперь у нашего класса больше возможностей, чем раньше.

Во всех других случаях использовать наследование нет необходимости.

Добавление объектов к прототипу.

Для начала выполним следующий код:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css">
<script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext/ext-all-debug.js"></script>
<title id="page-title">Extending Error: Object in prototype</title>
<script type="text/javascript">
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
});

});
</script>
</head>
<body></body>
</html>

Чего мы ожидаем ? Это написано в title панелей: Верхняя панель (p1) должна быть с синим бэкграундом, потому что мы установили ей этот параметр после того как создали объект. А у нижней панели (p2) должен быть красный бэкграунд, потому что он стоит по умолчанию в классе MyPanel.

Но она получается тоже голубой!!! Почему ? Причина проста panelConfig  это объект, который создается при определении класса и он добавляется к прототипу MyPanel. Объекты (массивы тоже) доступны по ссылке, получается что p1 и p2 используют один и тот же panelConfig. Устанавливая свойство bodyBg в методе applyBackground мы изменяем panelConfig. Поэтому мы создаем панель p2 с таким же голубым цветом.

Здесь вы сразу увидели ошибку, но устранение этой ошибки может занят у вас недели в реальных приложениях. Представьте например, что у вас прототип класса store.

Жесткая привязка к id.

Очень простой, но смертельной ошибкой является жесткая привязка наследуемого класса или его items, tollbars, buttons объектов к определенному id. Если мы жестко привязываемся к определенному id, мы не сможем создать несколько экземпляров нашего класса, ведь так ?

Вместо заключения.

Это пока все, но если я найду еще какие-либо ошибки, я обязательно добавлю их выше.

Оставайтесь с нами!

Источник: http://blog.extjs.eu/know-how/writing-a-big-application-in-ext-part-3/

Не забудьте прочитать первую и вторую часть этой статьи.