[Обсуждение] Обработка событий движка в javascript (замена старых хуков и маркеров)

Как я писал уже здесь есть планы полностью отказаться от хуков и маркеров в джаваскрптах движка. На мой взгляд стандартного механизма триггеров вполне достаточно для покрытия того функционала, который возложен на них. Кому интересна эта тема — добро пожаловать к обсуждению. Вот упрощенный пример, как сейчас используются маркеры и хуки:
ls.blog = (function ($) {
    this.toggleJoin = function(obj, idBlog){
        var params = {idBlog: idBlog};
        var url = '...';

        ls.hook.marker('toggleJoinBefore');
        ls.ajax(url,params,function(result) {
            ls.hook.run('ls_blog_toggle_join_after',[idBlog,result],obj);
        });
    };
});

Как это предлагается делать в новой парадигме:
ls.blog = (function ($) {
    this.toggleJoin = function(obj, idBlog){
        var context = this.toggleJoin;
        context.params = {idBlog: idBlog};
        context.url = '...';

        $('body').trigger('toggleJoinBefore.alto.blog', context);
        ls.ajax(context.url, context.params, function(result) {
            context.result = result;
            $('body').trigger('toggleJoinAfter.alto.blog', context);
        });
    };
});

И вот как можно обрабатывать эти события в сторонних плагинах:
$('body').on('toggleJoinBefore.alto.blog', function(event, context){
    context.params.otherParam = 123; // добавляем еще один параметр
});
/* ... */
$('body').on('toggleJoinAfter.alto.blog', function(event, context){
    if (context.result.bStateError) {
        // анализируем и обрабатываем результат
    }
});
Т.е. в функцию-обработчик события вторым параметром передается объект-контекст функции, в которой вызываются эти события, и мы можем в обработчике иметь доступ к любым свойствам контекста.

Плюсы нового подхода очевидны: избавляемся от самопальных «костылей» (и лишнего кода) и переходим к стандартным механизмам обработки событий. Возможно, есть какие-то недостатки, но я пока их не заметил.

Похожие статьи


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

0
Похоже, в последнем блоке кода ошибка, и вместо toggleJoinBefore. подразумевалось toggleJoinAfter.
0
Спасибо, поправил. И это, конечно, общая схема, в конкретной реализации могут быть некоторые изменения. Например, склоняюсь к тому, что лучше не trigger() использовать, а triggerHandler(). Плюс, можно попробовать не напрямую использовать триггер, а через некоторую обертку, чтобы контекст сразу в this передавать в функции обработчике. Или это лишнее уже?
0
Ну, я конечно за то, что бы сразу делать хорошо. Но, опять же, тяжело понять, где это «хорошо», пока не начнешь просто реализовывать и перебирать варианты. Честно сказать, у меня нет большого опыта в проектировании архитектуры JS кода, поэтому как вы решите все это оформить — значит, так и будет. В связи с решением использования триггеров буду просто придерживаться этого принципа на данный момент, а потом изменить свои проекты под ту архитектуру, которая будет впоследствии использоваться в движке, не должно составить большого труда.
+1
Согласен с предложением использовать триггеры, но есть еще особенности.
1. Сейчас весь js-функционал заключен в объект ls, который построен не по архитектуре плагинов jQuery. (Очень хороший топик по теме)

2. Объекты, входящие в состав частично не соответствуют jslint. Не обязательно, конечно, ему следовать, но все же… (http://habrahabr.ru/post/74419/)

3. Все объекты «ls.» подгружается полностью, и все его методы доступны на любой странице даже если они не используются. Я понимаю, что модульность в js это отдельная тема, но подгружать все скрипты, даже если они не нужны, тоже не стоит, imho. (Как вариант requirejs.ru/)

4. Нет системы используемых в коде js идентификаторов и классов кода html шаблонов.

Думаю, что стоит обратить внимание не только на триггеры, но и на общую архитектуру js-кода в Alto.
Отредактирован:
+1
Ох, Андрей, ну как всегда — если копнешь, так до самых глубин :) (это я в одобрительном смысле, если что)

Про JSLint помню. По большому счету, соглашения JSLint должны быть составной частью Alto Coding Style. А так же составной частью должны стать правила (кроме php и js) еще и для css и tpl.

Объект ls сейчас — неймспейс для большого набора функций. Нужно ли это оформлять, как jQuery-плагины? Честно говоря, не даже думал об этом, поэтому пока не могу ни согласиться, ни возразить. Если есть какие-то аргументы «за», то рад буду услышать.

Модульность js-скриптов — да, отдельная тема. Собственно, еще в ЛС был заложен механизм, позволяющий группировать js- и css-файлы в разных комбинациях и загружать на разных страницах разные наборы. Но как-то особо не прижилось пока. Рассуждая чисто теоретически, трудно сказать, какой подход лучше — сформировать один набор, который будет грузиться на всех страницах, либо делать разные наборы. В первом случае можем получить выигрыш за счет кеширования, во втором — за счет уменьшения размера наборов. Где выигрыш будет больше — это только эксперименты могут показать.

Но даже если оставлять, как есть (т.е. единый набор), то часть скриптов, бесспорно, имеет смысл вынести в «ленивую загрузку», напр., скрипты, связанные с редактированием — сам редактор, загрузка фото и аватар и т.д.
+2
Про соглашения согласен. Если определятся с правилами кодинга, то на всех используемых языках, а не только на PHP.

Нужно ли это оформлять, как jQuery-плагины?
Я считаю, что нужно — это, во первых, понизит «уровень вхождения» в код новых разработчиков. Во вторых, однообразит подход к разработке. В третьих, упростит читаемость кода…

Модульность js-скриптов
Я очень не уверен, что можно получить какие-то плюсы за счет манипуляций с кэшем и наборами скриптов. Модульный подход я рассматриваю как инструмент развития, который позволит построить более сложную систему в будущем.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.