Недавно я прочитал статью «Новые идеи для создания интерфейсных компонентов пользовательского интерфейса», написанную дядей Ю, которая напомнила мне статью, которой я поделился в прошлом году , «Шаблон проектирования JS для совместной разработки с чувствами» , которая вызвала небольшой резонанс. .
Говорят, что в новой версии кассового проекта Alipay в прошлом году я некоторое время пробовал эту модель кодирования компонентов. Вот небольшой опыт, которым я могу поделиться с вами:
Оглядываясь назад на упомянутый ранее абстрактный класс, студенты, которые что-то знают о шаблонах проектирования, могут найти его знакомым. Да, на первый взгляд он выглядит как абстрактная фабрика, но в сочетании со следующими базовыми классами вы обнаружите, что я не переопределил его. getVessel, show, Hide и другие методы в каждом базовом классе, но непосредственно унаследовали эти методы в абстрактном классе. Определенно найдутся люди, которые не понимают, зачем они это делают. Просто потому, что это JS, а не JAVA. Определенная степень связанности в обмен на достаточную гибкость, на мой взгляд, не является чрезмерной, не говоря уже о том, что этот абстрактный класс должен обеспечивать абсолютную стабильность. Необходимо, чтобы его нельзя было изменять по желанию после его формирования.
С помощью этого абстрактного класса я связываю объект контакта с объектом-контейнером и реализую простейшее взаимодействие между ними посредством метода действия. «Самый простой» означает не что иное, как операции отображения или скрытия, поэтому я определил методы отображения и скрытия. Очевидно, что «простейшее» поведение взаимодействия не может на 100% удовлетворить поведение пользователя, поэтому я должен установить метод setInterface и добавить классы эффектов к классам, которые требуют специальных эффектов взаимодействия. Наконец, избегайте прямого создания экземпляра этого абстрактного класса при его использовании. Напомните всем, кто работает в методе действия, что если вы хотите создать экземпляр операции, перейдите к определенному классу наследования, чтобы переопределить метод действия.
Через этот абстрактный класс мы можем наследовать самые основные компоненты aPop, dropDown, xbox, xTab и другие... Они уже упоминались в предыдущей статье, я не буду здесь вдаваться в подробности и сосредоточусь на объяснении этого. если написанные здесь базовые классы не могут удовлетворить особые потребности, как мы можем быстро разработать персонализированные компоненты.
Давайте возьмем xTab в качестве примера. Мы можем использовать этот компонент для завершения базового эффекта переключения между точками мультитач и несколькими контейнерами. Но что, если нам нужно добавить поверх этого некоторые анимационные эффекты? Давайте сначала посмотрим на код реализации вкладки унаследованного класса:
Можно обнаружить, что я выполнил метод setInterface после метода show. По умолчанию будет вызываться одноименный метод в абстрактном классе. Этот метод интерфейса предназначен для добавления дополнительных классов интерактивных эффектов для аналогичных интерактивных строк. Например: сейчас мы хотим разобраться с эффектом слайда, тогда нам нужно только наследовать класс приложения на основе xTab, переопределить метод setInterface и добавить класс анимации для достижения эффекта слайда и всё!
AP.widget.animTab = AP.widget.xTab.extend({
setInterface: функция (цель, судно) {
this.parent(цель,сосуд);
this.anim(судно);
},
животное: функция (сосуд) {
...
}
});
Честно говоря, это очень грубая дизайнерская идея, но она позволяет нам взглянуть на режим кодирования компонентов под другим углом. Вышеупомянутое — всего лишь несколько поверхностных попыток применения, и волнение будет продолжаться... ждем вас!
Перепечатка: http://ued.alipay.com/2010/06/propose-front-end-ui-comComponents-and-then-build-a-new-train-of- Thought/
AP.widget.xTab = AP.widget.basic.extend({
BindEvents: функция (цель, судно) {
E.on(цель,this.options.eventType,this.action,target,this);
E.on(окно,'load',this.oXtab,target,this);
},
действие: функция (е, цель) {
this.switchTab(e,target);
},
switchTab: функция (е, цель) {
...
for(i=0,len=tabs.length;i<len;i++){
var hash = tabs[i].href.split("#")[1];
вар сосуд = D.get(хеш + 'Расширить');
если(судно){
this.hide(судно);
}
D.removeClass(tabs[i].parentNode,'current');
if(target.href == tabs[i].href){
D.addClass(target.parentNode,'текущий');
если(судно){
this.show(судно);
}
//Устанавливаем различные интерфейсы приложения
this.setInterface(цель,судно);
}
E.preventDefault(е);
}
},
showTab: функция (индекс) {
...
},
//Инициализируем вкладку позиционирования
oXtab: функция (цель, е) {
...
}
});
AP.widget.basic = новый AP.Class({
setOptions: функция (опции) {
//Настройки интерфейса
},
инициализировать: функция (цели, параметры) {
//Метод инициализации, целью которого является установление связи между элементами подмножества целей и методом
},
getVessel: функция (цель) {
//Получаем контейнер, который удовлетворяет целевому отношению сопоставления
},
BindEvents: функция (цель, судно) {
//Привязываем здесь триггерное действие цели
},
действие: функция() {
//Функция выполнения, запускаемая событием, привязанным к цели, содержит логику, которую вы хотите выполнить.
},
показать: функция() {
//отображение контейнера
},
скрыть: функция() {
//скрываем контейнер
},
setInterface:функция(){
//Устанавливаем интерфейс, общий для каждого компонента
}
})