Каковы лучшие практики для разработки классов JavaScript, которые представляют объекты пользовательского интерфейса в DOM? - PullRequest
6 голосов
/ 05 июля 2011

Я очень хорошо знаком с JavaScript и ООП, но очень незнаком с проектированием классов JS, которые используются для программирования пользовательского интерфейса (HTML). Я немного искал, но не встречал каких-либо распространенных паттернов.

Допустим, я хотел динамически создавать панельные объекты (похожие на панели Microsoft Windows). Каждому объекту нужен контейнер, область заголовка, которая может содержать текстовую метку, и кнопку закрытия, которая имеет обработчик события щелчка. В дополнение к представлению DOM (HTML) объект также будет иметь представление объекта JavaScript (переменные и методы). Вот один из способов, которые я попробовал:

//
// Window class
//
var Window = function(params) {
    this.testMethod = function() {
        console.log('test');  // just an example
    }

    this.windowDiv = document.createElement('div');
    this.windowDiv.style.width = params.width + 'px';
    this.windowDiv.style.height = params.height + 'px';
    this.windowDiv.style.position = 'absolute';
    this.windowDiv.style.top = '30px';
    this.windowDiv.style.left = '30px';
    this.windowDiv.style.border = '1px solid #000';

    this.headerDiv = document.createElement('div');
    this.headerDiv.style.width = '100%';
    this.headerDiv.style.height = '30px';
    this.headerDiv.style.background = '#bbb';
    this.headerDiv.style.borderBottom = '1px solid #000';
    this.headerDiv.innerHTML = params.title;

    this.buttonDiv = document.createElement('div');
    this.buttonDiv.style.width = '30px';
    this.buttonDiv.style.height = '18px';
    this.buttonDiv.style.position = 'absolute';
    this.buttonDiv.style.top = '0px';
    this.buttonDiv.style.right = '5px';
    this.buttonDiv.style.textAlign = 'center';
    this.buttonDiv.style.background = 'red';
    this.buttonDiv.style.border = '0px 1px 1px 1px solid #000';
    this.buttonDiv.innerHTML = 'x';
    this.buttonDiv.addEventListener('click', function(e) {
        document.body.removeChild(e.target.parentNode.parentNode);
    }, false);

    this.headerDiv.appendChild(this.buttonDiv);
    this.windowDiv.appendChild(this.headerDiv);
    document.body.appendChild(this.windowDiv);
}

// Initialize
var myWindow = new Window({
    width: 400,
    height: 200,
    title: 'My Window'
});
myWindow.testMethod();

Это не кажется "правильным". Другой подход может состоять в том, чтобы иметь метод render () и использовать его для выделения кода генерации HTML. Кажется неловким, что объект JS содержит несколько вложенных объектов HTML внутри него. Должен ли я просто передать вложенные теги через innerHTML?

Так что мне любопытно ... какой здесь лучший подход? Каков наилучший способ разработки классов, имеющих код DOM (объекты HTML и стили) и традиционные переменные и методы? Есть ли способ использовать прототипы для этих объектов HTML? В этом примере вы даже можете себе представить, что есть также класс WindowManager, который содержит экземпляры объектов Window, помогает управлять ими и создает новые. И это тоже может иметь представление HTML.

Некоторые из вышеперечисленных могут быть обработаны с помощью статического CSS и применения идентификаторов / классов для очистки некоторого кода, но давайте просто скажем, что позиционирование и размер должны выполняться программно (для обработки изменения размера, перетаскивания и т. Д.) .

Меня не интересуют решения на уровне фреймворка, которые могут быть предоставлены ExtJS, jQuery и т. Д. Я хочу знать, каковы лучшие практики для собственного кода. На самом деле, мне было бы интересно узнать, как инженеры упомянутых фреймворков проектируют свои классы пользовательского интерфейса.

Ответы [ 2 ]

2 голосов
/ 05 июля 2011

Для HTML-части объекта вы можете использовать шаблон для определения HTML-структуры компонента, добавляя все необходимые данные при инициализации компонента.Есть много способов реализовать функцию шаблона, взгляните на пример underscore.js .

Для стилей я бы поместил значения по умолчанию в таблицу стилей.Неважно, если они должны быть изменены позже через JavaScript, это все равно будет работать, даже если они определены в CSS.Единственной информацией, которая должна быть в компоненте, является поведение по умолчанию различных событий, которые запускает этот компонент.

Вы также можете посмотреть на создание простой цепочки прототипов для помещения общих свойств в базовые «классы» (понимая, что у javascript нет реальных классов), снова обратитесь к underscore.js для примера функции расширения, которая выполняетэто, среди других реализаций, которые можно гуглить.

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

0 голосов
/ 05 июля 2011

Backbone.js хорошо подходит для ваших заявленных требований:

http://documentcloud.github.com/backbone/

Я храню html внутри шаблонов и загружаю их в визуальный элемент, которым управляет контроллер (динамически создаваемый div для каждого экземпляра). Это дает мне повторно используемые html-элементы, а также методы и свойства пользовательского интерфейса, характерные для каждого экземпляра пользовательский интерфейс.

...