Javascript-форум (https://javascript.ru/forum/)
-   ExtJS (https://javascript.ru/forum/extjs/)
-   -   ExtJS 5, синхронная загрузка ресурсов (https://javascript.ru/forum/extjs/47772-extjs-5-sinkhronnaya-zagruzka-resursov.html)

Infarch 06.06.2014 18:15

ExtJS 5, синхронная загрузка ресурсов
 
В моем приложении тексты выводятся в зависимости от языка пользователя, а на сервере хранятся в БД и изредка меняются. Поэтому я не могу просто прописать их в js файлах. Как выход, я создал синглтон который запрашивает тексты с сервера при создании.
Ext.define("Communication.config.LocalText",{
	singleton : true,
	constructor : function(config){
		console.log("constructor : Communication.config.LocalText");
		this.store = Ext.create("Ext.data.Store", {
			model: "Communication.model.LocalText",
			proxy: {
			type: "ajax",
				url : "/json?cmd=communication.translations",
				pageParam: "",
				startParam: "",
				limitParam: ""
			}
		});
		this.store.load();
	}
});


Предполагалось что я буду подключать его к тем вьюхам где нужны тексты, таким вот образом:

Ext.define("Communication.view.TabMenu", {
	extend: "Ext.tab.Panel",
	alias: "widget.tabmenu",
	requires: [
		"Communication.config.LocalText"
	],
	initComponent: function() {
		Ext.apply(this, {
			items: [
				{
					title: Communication.config.LocalText.getText("heading", "history")
				}
			]
		});
		this.callParent(arguments);
	}
});


Но возникла проблема: загрузка то асинхронная. Так что, когда я обращаюсь к этому синглтону и вызываю getText(), часто бывает что текстов еще нет. Я пытался сделать цикл после load для ожидания, но тут уже браузер возмущается что скрипт не отвечает. Подскажите пожалуйста, как бы вы решили эту проблему?

siber-biber 07.06.2014 07:36

Генерим на сервере такой класс например:
Ext.define("MyApp.Locale", {
    singleton : true,
    
    get : function (id) { return this.phrases[id]; },

    phrases : {
        'yes' : 'Да',
        'no' : 'Нет',
        ...
    }
});
То есть вместо статического MyApp.Locale.js на сервере выполняется скрипт который наполняет его действующими локалями.
На PHP например как-то так:
Ext.define("MyApp.Locale", {
    singleton : true,

    get : function (id) { return this.phrases[id]; },
    
    phrases : <? json_encode($active_locale_translations) ?>
});

Infarch 09.06.2014 11:02

Да, такая мысль была. Но проблема в том, что у меня ВСЕ генерируемые сервером файлы доступны по такому вот урлу: "/controller?cmd=...". А экст ищет свои ресурсы по другим путям. В частности, этот файл локали будет искаться по пути MyApp/app/Locale.js. Вот если бы можно было для отдельного файла заменить путь... Или можно?

Infarch 09.06.2014 12:23

В общем, проблему решил определив этот источник текстов в index.htm, благо он как раз на сервере генерится. Костыль конечно, но пока пусть поработает, может потом лучше придумаю.

siber-biber 09.06.2014 13:18

на сервере можно урлы красивые рисовать средствами вебсервера ..mode_rewrite например для апача

Infarch 10.06.2014 11:26

Цитата:

Сообщение от siber-biber
mode_rewrite

Можно, но править конфиги апача клиент не разрешает. Только в том случае если это нужно 100%. Видимо будем жить с костылем. И кстати... в процессе разработки приложения на ExtJS5 все файлы лежат по своим папкам и запрашиваются каждый раз заново. Но при деплойменте они все пакуются в один, который будет кешироваться браузером. Так что мод реврайт отпадает.

siber-biber 10.06.2014 20:32

Цитата:

Сообщение от Infarch (Сообщение 315849)
Можно, но править конфиги апача клиент не разрешает. Только в том случае если это нужно 100%. Видимо будем жить с костылем. И кстати... в процессе разработки приложения на ExtJS5 все файлы лежат по своим папкам и запрашиваются каждый раз заново. Но при деплойменте они все пакуются в один, который будет кешироваться браузером. Так что мод реврайт отпадает.

Можно продолжать юзать динамическую загрузку ..встречал проекты где так делают и в продакшене. Хотя чаще собирают в один файл.

Ну ок ..если это один файл, можно делать так:
<script src="MyApp/Locale.js"></script>
..или так:
Ext.Loader.loadScript({
    url     : 'MyApp/Locale.js',
    onLoad  : function() {
        ...
    }
});

Infarch 11.06.2014 14:04

Собирать будем 100%. Ну а ресурсы инициализирую в индексе, он то генерится на сервере. Пусть уж так...

bankir 24.06.2014 13:45

Я делаю вот так:

var loadMask;

	var verifyStoreLoads = function(){
		var ret = true;		
		var filStore = controller.getFilialsStore();
		ret = ret&&filStore.isLoadedSuccessful;
		var divStore = controller.getDivisionsStore();
		ret = ret&&divStore.isLoadedSuccessful;
		return ret;
	}
	
	var preRun = function(){	
		if (!loadMask){
			loadMask = new Ext.LoadMask(globaldatapanel, {msg:'Загрузка справочников...'});
			loadMask.show();
		}
		var ret = verifyStoreLoads();
		if (ret){
			loadMask.hide()
			loadMask.destroy();
			run();
		}
		else
			setTimeout(preRun,1000);		
	}


ну а в сторе вешаю слушатель
isLoaded:false,
        isLoadedSuccessful:false,
        listeners:{
		load: function(store, records, successful, eOpts){
			store.isLoaded = true;
			store.isLoadedSuccessful = successful;
		}
	},


В итоге, пока сторы не загружены, висит сообщение "Загрузка справочников..."


Часовой пояс GMT +3, время: 21:29.