ExtJs 4 и платформа Bars.B4
ведущий разработчик, БАРС Груп, БЦ ЖКХ
JavaScript + OOP = ExtJs 4
Ext.util.Observable соответсвует path/to/src/Ext/util/Observable.jsExt.form.action.Submit соответсвует path/to/src/Ext/form/action/Submit.jsMyCompany.chart.axis.Numeric -> path/to/src/MyCompany/chart/axis/Numeric.jsCamelCase - наше все
Было:
Ext.ns('My.cool');
My.cool.Window = Ext.extend(Ext.Window, { ... });
Стало:
Ext.define(className, members, onClassCreated);
Ext.define('My.sample.Person', {
name: 'Unknown',
constructor: function(name) {
if (name) {
this.name = name;
}
},
eat: function(foodType) {
alert(this.name + " is eating: " + foodType);
}
});
var aaron = Ext.create('My.sample.Person', 'Aaron');
aaron.eat("Salad"); // alert("Aaron is eating: Salad");
<html>
<head>
<title>Account Manager</title>
<link rel="stylesheet" type="text/css" href="ext-4/resources/css/ext-all.css">
<script type="text/javascript" src="ext-4/ext-debug.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body></body>
</html>
Ext.application({
requires: ['Ext.container.Viewport'],
name: 'AM',
appFolder: 'app',
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
xtype: 'panel',
title: 'Users',
html : 'List of users will go here'
}
]
});
}
});
Ext.define('AM.controller.Users', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'viewport > panel': {
render: this.onPanelRendered
}
});
},
onPanelRendered: function() {
console.log('The panel was rendered');
}
});
Ext.define('AM.view.user.List' ,{
extend: 'Ext.grid.Panel',
alias: 'widget.userlist',
title: 'All Users',
initComponent: function() {
this.store = {
fields: ['name', 'email'],
data : [
{name: 'Ed', email: 'ed@sencha.com'},
{name: 'Tommy', email: 'tommy@sencha.com'}
]
};
this.columns = [
{header: 'Name', dataIndex: 'name', flex: 1},
{header: 'Email', dataIndex: 'email', flex: 1}
];
this.callParent(arguments);
}
});
Ext.define('AM.model.User', {
extend: 'Ext.data.Model',
fields: ['name', 'email']
});
Ext.define('AM.store.Users', {
extend: 'Ext.data.Store',
model: 'AM.model.User',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'data/users.json',
reader: {
type: 'json',
root: 'users',
successProperty: 'success'
}
}
});
Ext.define('CanSing', {
sing: function() {
alert("I'm on the highway to hell...")
}
});
Ext.define('Musician', {
mixins: ['CanSing'],
sing: function() {
// делегируем операцию singing mixin-у
this.mixins.canSing.sing.call(this);
}
})
Ext.define('GridActs', {
...
alias: 'widget.gridacts',
gridSelector: null // селектор, который будет использоваться для получения grid'a
...
});
Ext.define('MyController', {
extend: 'B4.base.Controller',
aspects: [
{
xtype: 'gridacts',
gridSelector: 'mygrid' // конкретный селектор
}
]
});
Создать контроллер унаследовав его от B4.base.Controller и добавить ему миксин
Ext.define('MyApp.MyController', {
extend: 'B4.base.Controller',
mixins: {
context: 'B4.mixins.Context'
}
});
Определить конфигурацию для роутов:
Ext.define('MyApp.MyController', {
extend: 'B4.base.Controller',
mixins: {
context: 'B4.mixins.Context'
},
config: {
routes:[
{
route: 'contractor/{id}/', //регулярное выражение
fn: 'index' // имя функции
}
]
}
});
Определить функции, соответствующие роутам:
Ext.define('MyApp.MyController', {
... все то же самое, как выше
index: function(id){ // функция в качестве параметра получит значение из url
// например, если открыли url http:///#contractor/1/
// то функция index при вызове получит в качестве параметра 1
// Если нам нужно добавить компоненту в главный контейнер
// 1. Получаем компоненту, например, так:
var view = this.getMainPanel() || Ext.widget('contractor_nav_panel',
{
title: 'Контрагент ' + id
});
// ВАЖНО!
this.bindContext(view); // 2. привязываем компоненту к текущему контексту
this.application.deployView(view); // 3. деплоим ее через application (подробнее о деплое ниже)
}
});
По умолчанию при вызове this.application.deployView(view) метод defaultDeploy из PortalController.
Если вы хотите, чтобы ваш контроллер имел возможность добавлять компоненту в пользовательский интерфейс и контекст приложения при этом нормально работал, надо сделать следующее:
Добавить в контроллер объект deployViewKeys:
Ext.define('MyApp.MyController', {
...
deployViewKeys:{
'deployViewItem': 'deployViewItemFn'
}
});
Здесь 'deployViewItem' - ключ, который будет передаваться в качестве второго аргумента this.application.deployView(view, 'deployViewItem'), 'deployViewItemFn' - имя функции, которая будет ответственна за добавление компоненты. Ее тоже необходимо определить самому.
В качестве примера можно посмотреть на реализацию defaultDeploy из PortalController
namespace Bars.Gkh.Overhaul
{
using Bars.B4;
public class ClientRouteMapRegistrar : IClientRouteMapRegistrar
{
public void RegisterRoutes(ClientRouteMap map)
{
map.AddRoute(new ClientRoute("workprice/", "B4.controller.dict.WorkPrice"));
map.AddRoute(new ClientRoute("commonestateobject_create/", "B4.controller.CommonEstateObject", "create"));
map.AddRoute(new ClientRoute("commonestateobject_edit/{id}/", "B4.controller.CommonEstateObject", "edit"));
}
}
}
{
xtype: 'permissionaspect',
applyBy: function (component, allowed) {
if (allowed) {
component.enable();
} else {
component.disable();
}
}
applyOn: { event: 'show', selector: '#meetingActionWindow' },
permissions: [
{ name: 'TM.Protokol.View', applyTo: '#meetingActionWindow #btnProtocol' },
{ name: 'TM.Analytic.View', applyTo: '#meetingActionWindow #btnAnalytics' }
]
}
/
#