Ajax

Доброго времени. Такая проблема, точнее вопрос:

Есть экшен, на котором есть какие-то данные (текст, JS). Надо получить данные из этого экшена и вывести.


Делаю так:

var ls = ls || {};

ls.name = (function ($) {
	this.namename = function() {
		$.get(aRouter['name'], function( data ) {
	            $( ".result" ).html( data );  
		});
	}

	return this;
}).call(ls.name || {},jQuery);

jQuery(document).ready(function($){
	/**
	 * init
	 */
	ls.name.namename();
});


Оно работает, но хотелось бы сделать в стилистике LS, т.е. вида ls.ajax. Оно работает только с POST? Как сделать GET? Или как сейчас нормальное решение? Поясните пожалуйста неразумному.

11 комментариев

avatar
Как вариант, что бы не зависить от LS ajax:

Просто используйте в Ивенте Экшина конструкцию вида:

public function EventSomeDataFetch(){
        $this->Viewer_SetResponseAjax('json');
        $currentUser = $this->User_GetUserCurrent();
        if(!$currentUser or !$currentUser->isAdministrator()) {
            $this->Message_AddErrorSingle('Ошибка! Пользователь не авторизован!');
            return;
        }
        $data=$this->PluginSomeplugin_Someplugin_getSomedata($currentUser->getId());
        $this->Viewer_AssignAjax(self::DATA, $data);
 }


В Ивенте, соответственно, можете использовать данные GET, POST, как и в обычных, неаджаксовых ивентах.


На клиенте принимаете данные, парсите и выводите. Добавьте обработчик ошибок и вывод всплывающих нотификейшинов, как это сделано в ls.ajax при желании.
avatar
Спасибо, буду думать.
avatar
Вот один из вариантов который я использовал в связке с Backbone.js:

Дополняете базовый ajax возможностью обработки сообщений об ошибках и нотификейшинов.

ajax : function(settings){
			settings.url = settings.url + '?security_ls_key='+this.get('security_ls_key');
			if(!('dataType' in settings)) {
				settings.dataType = 'json';
			}
			var self = this;
			var oldSuccess = settings.success;
			var oldError = settings.error;
			settings.success = function(xhr){
				if(!!xhr.sMsg) {
					if(xhr.bStateError){
						self.errorMsg(self.get('appLang')[xhr.sMsg]);
					} else {
						self.noticeMsg(self.get('appLang')[xhr.sMsg]);
					}
				}
				if(oldSuccess) {
					oldSuccess.apply(this,Array.prototype.slice.call(arguments));
				}
			};
			settings.error = function(xhr){
				if(xhr.status === 404){
					self.router.navigate('/app/admin',{trigger:true,replace:true});
				}
				if(oldError) {
					oldError.apply(this,Array.prototype.slice.call(arguments));
				}
			};
			return $.ajax(settings);
},


И далее можете использовать в таком виде:

app.ajax({
                url : 'some_module/some_event',
                data: qParam, //ваши данные 
                type : 'GET',
                success : function(res){
                    // Ваш парсер или что-тоотвечающее за вывод данных
                },
                error : function(){
                    // Ваш обработчик ошибок
                }
});
avatar
Круто, благодарствую, некоторые вещи не понятны, но надо потыкать просто! Посоветуйте, стоит ли вообще заморачиваться. Смотрите, у меня на экшене только:

{if}
js
текст
{/if}


т.е. нет никаких данных, которые меняет пользователь, статика по сути. А ajax-ом буду переодично подгружать экшен, если условие выполнено, показывать скрипт. М.б. лучше использовать стандартный $.get?
avatar
Давайте вкратце объясню, как «устроен» аjax в LS, а вы решите, какой вариант лучше для вашей задачи. У вас замечательные шаблоны, и, возможно, вы решите их дополнить интерактивными фишками )
1. Вы делаете ajax запрос на сервер, передавая данные в get или post.
2. Ваш экшин получает эти данные, вы что-то с ними делаете, и формируете ответ клиенту (браузеру).
3. Ответ клиенту в LS имеет стандартный вид (вне зависимости, каким способом вы сделали запрос), это json-объект:
{
bStateError: false
data: true
sMsg: ""
sMsgTitle: ""
}


4. Разберем поля, и найдем откуда они берутся:
bStateError — признак несистемной ошибки. Т.е., вы просто хотите сказать пользователю, что его запрос ошибочен, но ошибка не критична (т.е., это не системная ошибка сервера, запрос обрабатывается корректно). Можно показать пользователю pop-up с сообщением об ошибке, или использовать в других целях, например, перебросить пользователя на другую страничку.
Что бы сформировать признак ошибки достаточно в Ивенте добавить «формирователь» ошибки, например:
$this->Message_AddErrorSingle('Ошибка! Вы не авторизованы!');

Этот формирователь ошибок сформирует корректный json ответ клиенту.
В поле sMsgTitle будет текст ошибки, а в поле bStateError — признак ошибки. Поле data будет пустым.
sMsg — поле тела сообщения об ошибке, формируется вторым параметром метода Message_AddErrorSingle. При желании.

data — поле с вашими json-данными для правильного, «безошибочного» ответа клиенту. Формируется методом Viewer_AssignAjax, например:
$this->Viewer_AssignAjax('data', $data);


Первый параметр метода отвечает за название поля, в котором будет находится json-ответ с данными, второй параметр — значение передаваемой переменной, объекта массива или чего-то, подлежащего преобразованию в json-объект.

Т.е., в data вы помещаете то, с чем хотите работать на клиенте.

5. Обработка данных на сервере.
К примеру, ваш Ивент имеет следующий вид:
    /**
     * Fetch all public Blogs
     */
    protected function EventFetchBlogs(){
        // Устанавливаем ответ типа JSON
        $this->Viewer_SetResponseAjax('json');
        // Берем текущего пользователя и проверяем,
        // залогинен ли он, и ялвяется ли администратором 
        $currentUser = $this->User_GetUserCurrent();
        if(!$currentUser or !$currentUser->isAdministrator()) {
            // Если нет, отправляем клиенту ошибку
            $this->Message_AddErrorSingle('Ошибка! Вы не залогинены или не являетесь админом!');
            return;
        }
        // Берем из базы все блоги, используя метод модуля SomeModule 
        // (предполагаем, что ответ — ассоциативный массив списка блогов)
        if(!$data = $this->PluginSomeplugin_SomeModule_getBlogs()) {
            // Если нет блогов, возвращаем пользователю ошибку
            $this->Message_AddErrorSingle('Ошибка! Блоги не найдены!');
            return;
        }
        // Вормируем сообщение о успешной находке блогов
        $this->Message_AddNoticeSingle('Блоги найдены!');
        // Помещаем в поле ajax ответа "data" наши найденные блоги (ассоциативный массив)
        $this->Viewer_AssignAjax('data', $data);
    }


6. Обработка данных на клиенте
Формируем «наш ajax».

// Параметры запроса. Будут преобразованы либо в строку для GET либо в тело для POST
var params = {
    //Какие-то пары ключ-значение для обработки на сервере
    width:1680,
    height:1050,
    //Обязательный параметр для корректной обработки запроса в LS.
    security_ls_key: _ВАШ_SEQURITY_LS_KEY_ОБЯЗАТЕЛЬНЫЙ_ПАРАМЕТР_
};
$.ajax({
    // Устанавливаем тип запроса
    type : 'GET',
    // Путь для Ивента
    url: 'http://site.tld/someplugin/someevent',
    // Данные запроса. Автоматически преобразуются либо в строку, либо в тело
    data: $.param(params),
    // При успешном запросе
    success : function(xhr){
        // Проверяем, есть ли от сервера какие-либо сообщения
        if(!!xhr.sMsg) {
            // Если установлен флаг ошибки, обрабатываем, как сообщение об ошибке
            // Если флага нет — значит это сообщение об успехе
            if(xhr.bStateError){
                 // Выводим сообщение об ошибке xhr.sMsg;
                console.debug('Сообщение об ошибке', xhr.sMsg);
            } else {
                // Выводим сообщение об успешном запросе xhr.sMsg;
                console.debug('Сообщение об успехе', xhr.sMsg);
            }
        }
        // Если есть какие-либо данные в поле дата
        if(xhr.data) {
            // Выводим содержимое поля data
            console.debug('Принятые данные', xhr.data);
        }
    },
    // При неуспешном запросе. LS умеет обрабатывать только ошибки 404
    error :  function () {
        if(xhr.status === 404){
            //Что-то делаем при системной ошибке 404
            console.debug('Системная ошибка!', xhr.status);
        }
    }
});
avatar
Большое человеческое спасибо! Как раз для шаблонов хочу фишку сделать :)
avatar
верно, но вместо $.ajax можно использовать ls.ajax, который ключ безопасности передаст сам. также нет обязательного поля data в ответе на аякс запрос.
avatar
На счет поля
data
, да, верно, оно не обязательное. Может быть, может не быть.
avatar
Хорошо бы если Максим добавил в документацию работу с Ajax.
avatar
в какую документацию? :)
avatar
Ну не знаю сюда, или сюда или сюда. Так как мне лично не все очевидно было, когда искал информацию, хотя сейчас есть этот топик :)
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.