Как стать автором
Обновить

Комментарии 51

Шикарная статья, спасибо, особенно понравилось «наследование» :)
Плохая статья, слишком маленькая. Пишите еще, и побольше.
Мне показалось, что вдаваться в дальнейшие подробности будет уже суесловием.
Я имел ввиду, что статей по Jquery UI побольше хочется видеть :-)
Собственно, про то, как это устроено, я рассказал:) Можно, конечно, написать какой-нибудь виджет и подробно его разжевать… Писать про «коробочные» — неинтересно, есть документация с демо и кодом.
По коробочным действительно все ясно, а вот написать свой и рассказать вообще про какие-нибудь интересные кейсы использования — я бы почитал) но это так… мнение одного человека.
Про интересный кейс — будет, см. секцию «Заключение»;)
Написание своего тоже разжую, есть идея.
НЛО прилетело и опубликовало эту надпись здесь
Имхо mootools лучше плюшку для этого реализовала, создание класса более наглядное, как и наследование, в jq с этим проблема. UI мне не особо нравится касательно кода. Обычно я юзаю jquery tools там реализация более грамотная и гибкая. Если нужен дополнительный функционал или сам пишу или ищу адекватный плагин.
А переопределение функций — сомнительное решение
Переопределение?
Статья не про mootols. И даже не про создание классов.

Существует много проектов, написанных на jQuery + UI, с этим приходится считаться и использовать то, что есть.
ну да там пара функций стандартный jq переопределяются. Статья не о мутулс, я высказывал своё мнение, что если сравнивать создание классов и наследование то мутулс лучше. виджет — это класс, разве создавая виджет вы не класс создаете?
давно не использую ui как основу, разве что datepiker и так по мелочи если функционал 1 в 1. Проектов то много но инструменты то надо использовать с умом! Я же не критиковал вашу статью, что она не правильная, просто предложил на мой взгляд более удобные альтернативы.

Главный плюс что структура ui заставляет вас хоть как то использовать грамотно структурированный код. А не тупо куча кала в jq функционале )) к слову щас работаю с проектом, там вторую неделю хочу сломать нос создателю fancybox за криворукость, плагин из разряда я вообще прогить не умею поэтому подключу чтоб картинки показывал, вот верстальщик с ним наверстал кучу попапов, а теперь связать их — гемморой
Плагинов к jQuery много кривых, это да.
Статья хорошая, объясняет не совсем нормальную доку по написанию виджета на сайте jQueryUI.

По поводу наследования, на сколько я помню, там оно очень бедненькое и методы не наследует в классическом смысле, а делает тупо $.extend, что не дает достучаться до методов предка. (Во всяком случае я способа не нашел)
Ох, напутал я там в коде, прощу прощения. Поправил секцию про наследование.

Там да, $.extend, но не самого наследуемого виджета, а его prototype. Так что достучаться можно.
Да, делал в одном из своих проектов свои виджеты. Весьма удобно. В частности я делал простую таблицу, а потом расширял ее до таблицы с сортировкой.
Помнится Илья Кантор проводил различие между плагинами и виджетами, я с ним в принципе согласен. Виджеты это блок, а плагин это функция. Соответственно плагины делаем на основе jQuery, виджеты на основе jQuery UI.
Это так, к слову пришлось=)
Я согласен. Но про плагины уж не стал писать, избитая тема, имхо:)
Это да, я про заголовок=)
Ах да, действительно.
Объясню почему. Во-первых, навешиваются они так же, как плагины. Во-вторых, граница размыта — «большой плагин или маленький виджет?». В-третьих, не хотелось начинать с грозного «виджеты» в заголовке — народ обычно думает об этих штуках, как о плагинах. В-четвертых, определение все-таки не общепринятое.
В следующей статье обязательно расскажу, в чем разница:)
это он о логическом скорее разделении. Все равно с програмной точки зрения плагин и виджет совершенно одно и тоже ибо к jq крепятся одинаково. просто существует плюшка $.widget котрая помогает структурировать код и делает некую часть работы за вас
Было бы не плохо, показать пример того, зачем все это нужно.

Например, написать свой простой полезный виджет на jQuery UI.
Затрудняюсь объяснить, зачем это нужно. Зачем вообще модульность в коде?:)

Напишу, есть планы.
Вот я не мега программист, мне пока не понятно. Без подколов, серьезно.

Нужны мне табы — использую $.tabs(), нужен всплывающий диалог — $.dialog(). Для jQuery написано огромное количество плагинов и я их просто использую.

Хотелось бы понять, нужно ли тратить время на изучение модульности, если и сейчас все окей?
Бывает же, что затраты времени и сил не окупаются.

Напишите пожалуйста подробнее, на примере. Типа, стандартным путем тут 10 строк кода, а если вот так — то 5 :-)
Прочтите «Совершенный код» Макконела. Вкратце, модульность дает несколько вещей.
Во-первых, возможность сосредоточиться на одной задаче за раз.
Во-вторых, можно распаллалелить задачи.
В-третьих, она упрощает поддержку — проще локализовать баг, проще расширять функциональность.

Вы используете виджеты из комплекта — прекрасно, в секции «Наследование» вы найдете то, что может пригодиться.
Я не призываю прямо щас сесть и все переписать на виджеты. Но лучше знать, что такая возможность есть, не правда ли?
Опять общие фразы.
Я же просил на примере показать. А в ответ — прочти книгу и все поймешь. Окей, наверное, мне пока рано в это лезть :-)
Ну потому что это действительно общая вещь. Это просто хорошая практика. Это не артефакт, который дает +10 INT + 20 WIS:)
Поясню на примере.
Почему Объектно ориентированное программирование — хорошо?
Потому что, ты можешь написать одну функцию, которая будет выполнять какое-то действие, и вызывать ее в любом месте своей программы. К примеру, функция форматирования времени:

  function timeFormat($time) {
    return strftime('%d.%m.%Y', strtotime($time));
  }

Теперь, когда нужно вывести в привычном виде дату, можно просто выполнить
echo $this->timeFormat('2011-05-27');

и получить время в нужном виде. Вместо указания точной даты, конечно же, надо подставлять переменные, из sql запроса, например.

А еще, можно задать переменную для формата даты, и просто меняя ее получать другой результат.

  var $time_format = '%d.%m.%Y'; // Это шаблон для даты, можно поменять когда угодно

  function timeFormat($time) {
    return strftime($this->time_format, strtotime($time));
  }


Вот в таком виде лично мне бы хотелось увидеть топик про модульность.
Вы немного перепутали ООП с функциональным программированием. Но автор, думаю, поймет аналогию)
ФП тут нет, вторая функция не является чистой:) ООП тут тоже не густо:)
Ну да, я видел "$this". Просто немного удивило это: «Почему Объектно ориентированное программирование — хорошо?
Потому что, ты можешь написать одну функцию, которая будет выполнять какое-то действие, и вызывать ее в любом месте своей программы.» Но наверно просто не выспался и придираюсь)
Ну ей богу. ООП — это один частных случаев модульности. Функции — тоже.
Я согласен, что пример «на пальцах», например как во всеобщеизвестной доке в двух частях по написанию виджета (где также рассказывается почему нужно использовать виджеты), было бы ОЧЕНЬ хорошо иметь. Как раз для продолжения подоходит. ;)
спасибо большое, очень не хватает статей на русском по jQuery UI

с недавних пор успешно используем UI как стандарт кодирования в наших проектах, всё очень нравится, но вот о том, что на каждый элемент в коллекции (к которой применяется виджет) создается по отдельному экземпляру — не задумывался. теперь надо будет переписать старый код некоторый :)
В целом статья хорошая как вводная, но в ней есть ряд ошибок:

1) В разделе «Магия $.widget» про options:
Если при вызове виджета передать объект, то переданный объект будет «смерджен» (с помощью метода $.merge) с дефолтными настройками еще до вызова _create.

На самом деле используется $.extend(), ну и тогда уж объект будет «расширен».

2) Далее там же:
За работу с настройками отвечает метод setOption

Если это метод именно этого «нового» виджета — то вопросов нет, но если говорится о базовом методе (судя по примеру вызова) — то это не так. В виджетах есть public метод options( key, [ value ] ) и private методы _setOption, _setOptions.

И небольшое замечание по поводу раздела «Коллбэки»:
1) Если вызывается .bind() на элементе, то тип события надо указывать с префиксом в виде имени виджета, т.е. для примера в тексте должно быть: mw.bind('mywidgetonafterrender', function(evt, data) {console.log(data.theAnswer)});
2) В методе _trigger() тип события (строковый) всегда приводится к нижнему регистру, поэтому и в .bind() тип события должен быть в нижнем регистре полностью, но при этом для обработчика в опциях регистр учитывается — поэтому лучше для единообразия всё указывать в нижнем регистре.
Ещё забыл про раздел «Наследование»:
К сожалению, приходится явно указывать предка и вручную вызывать его конструктор.

Ну без указания предка никуда, а вот если _create() пустой, то и объявлять его не надо и конструктор вручную вызывать тогда не придётся.
Ну, это-то понятно, что если конструктор тривиальный, то зачем его вызывать:)
Тут дело не в вызове, а в том, что если в вашем прототипе (описании виджета) не будет метода _create — то останется метод базового виджета. Т.о. если в вашем конструкторе нет ничего, кроме вызова конструктора базового виджета, то и писать его не надо, в таком случае останется конструктор базового виджета. Хотя и конструктором-то его можно назвать с большой натяжкой — это просто метод, который вызывается при создании инстанса виджета.
А, вот оно что… Спасибо, это я как-то не сообразил.
1) Да, конечно. У меня какое-то помрачение было:(

2) Странно, у меня было другое ощущение… да и setOption вроде бы вполне работает.
Я проверю и поправлю статью соответствующим образом.

3) Вот это я не учел, спасибо.

С вашего позволения, я внесу исправления в соответствующих местах, и упомяну вас в пост-скриптуме с ссылкой на этот комментарий. Не возражаете?
2) Да, ваш метод работает как метод, он же написан, почему бы ему не работать, я про то, что базового такого метода нет. Т.е. если убрать именно ваш метод, то работать будет нечему, а в пояснительном тексте говорится о базовом методе — возможно это просто неясно изложено было.

Поправить, конечно, надо, на то и существует режим редактирования :) А уж упоминать ли мои комментарии в пост-скриптуме — это ваше право, комментарии всё равно никуда не денутся и редактировать их нельзя, но мне будет приятно.
Я имел ввиду, что если имплементировать метод setOption, то он будет отзываться на вызов .mywidget('option', …).
Сомнительный факт для меня. Вот если метод "_setOption" — то соглашусь, что он будет вызываться, но при этом надо учитывать, что метод базового виджета тоже не просто так и его либо надо вызывать, либо умышленно и осознанно не вызывать, отвечая за последствия.
Расскажите поподробнее, пожалуйста, какой механизм работает, когда мы делаем .mywidget('option', …)?
Вызывается метод виджета .option(), который в свою очередь если требуется чтение — то возвращает значение нужной опции (или всех), а если требуется запись — то вызывает метод _setOptions(), а тот в свою очередь вызывает уже _setOption().
Детали можно посмотреть самому — там всё просто: github.com/jquery/jquery-ui/blob/1-8-stable/ui/jquery.ui.widget.js#L186
Все, я понял вас, спасибо.

А как бы вы доопределили поведение виджета в ответ на изменение того или иного ключа, не трогая унаследованные функции?
Если речь про опции, то
1) не трогая можно сделать метод(ы), который будет что-то делать и менять опцию, а в описании опции тогда надо писать, что напрямую её менять не рекомендуется
2) либо (правильнее на мой взгляд) переопределить метод _setOption() и внутри нового метода обработать свой специфичный ключ опции и/или вызвать метод базового виджета.
Ок, так и запишем:)
И отдельно хочу заметить про заключение:
Допилив метод $.widget напильником, можно получить виджеты, которые сами читают свои настройки из разметки, сами находят витальные для себя элементы, и автоматически организовываются в иерархическую структуру. Но это явно тема для отдельной статьи.

Виджеты и так умеют читать свои настройки из разметки при наличии и соответствующей настройке плагина $.metadata.
Если под «допилить напильником» имеется в виду «взять исходник и поправить его» — то, на мой взгляд, это плохая идея. Потому что того, что есть сейчас вполне хватает для тех задач, которые встают перед виджетами jQuery UI. А вот если автор хочет написать свою фабрику виджетов (вполне можно взять за отправную точку идеи и часть кода из существующей фабрики) — то это благородная цель, но важно помнить, что у этой фабрики будут свои цели, задачи и область применения, и они должны быть обоснованными. Т.е. я хочу сказать, что метод, который используется в 1-ом виджете из 10, не нужен в базовом классе, он просто будет загромождать код.
Ну, то, что я сделал в своем pet-project, на данный момент больше похоже на monkey-patсhing, это да. Но просто потому что поправить нужно было буквально только в двух местах; переписывать из-за этого весь код заново не хотелось. Связано это с тем, как работает фабрика виджетов с опциями и всем остальным.

Кроме этого, мне хотелось сделать что-то все-таки цельное — уйти от концепции библиотеки методов, на каковую так ориентирована jQuery, и приблизиться к неким зачаткам фреймворка для построения приложений. При этом мне хочется описывать мои виджеты декларативно — отсюда желание автоматизации чтения настроек и т.д.
А почему статья не в блог jQuery?
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.