2012-06-11 3 views
0

Я пытаюсь создать пару пользовательских объектов в JavaScript, и я не уверен, что я собираюсь сделать все правильно.Как пользовательский объект прослушивает события дочернего пользовательского объекта?

У меня есть два объекта: «UserInterface» и «VolumeSlider». До этого момента эти два объекта были независимыми, но связаны с помощью методов. Я решил, что UserInterface должен вместо этого «иметь» VolumeSlider.

Итак:

UserInterface = { 
    _volumeSlider: null, 

    initialize: function() { 
     this._volumeSlider = VolumeSlider; //TODO: Should this be a new volumeSlider(); 
     this._volumeSlider.initialize(); 

     //I want to setup a listener for VolumeSlider's change-volume events here. 
    } 
} 

VolumeSlider = { 
    _volumeSlider: null, 

    initialize: function() { 
     this._volumeSlider = $('#VolumeSlider'); 
     var self = this; 
     this._volumeSlider.slider({ 
      orientation: 'horizontal', 
      max: 100, 
      min: 0, 
      value: 0, 
      slide: function (e, ui) { 
       self.passVolumeToPlayer(ui.value); 
      }, 
      change: function (e, ui) { 
       self.passVolumeToPlayer(ui.value); 
      } 
     }); 
    }, 

    passVolumeToPlayer: function (volume) { 
     if (volume != 0) 
      UserInterface.updateMuteButton(volume); 
     else 
      UserInterface.updateMuteButton('Muted'); 
    } 
} 

Вопрос два раза:

  • Является ли это хорошо способ создавать свои объекты и установки детей?
  • Я бы хотел, чтобы UserInterface мог отвечать на изменения и слайд-события VolumeSlider._volumeSlider вместо того, чтобы быть явно указанными. Как я могу это сделать?

ответ

1

Является ли это хорошим способом создания объектов и создания детей?

Если это работает, это «хорошо» :)
Но во всей серьезности, есть практически бесконечное число способов, чтобы установить что-то подобное до. Зависит от ваших потребностей.

Я скажу, однако, что ваш код будет громоздким, если, например, должно быть больше 1 ползунка.


Я хотел бы, чтобы быть пользовательский интерфейс в состоянии реагировать на событие изменения и слайда VolumeSlider._volumeSlider вместо того, чтобы быть явно сказано. Как я могу это сделать?

Я бы просто пропустил объект VolumeSlider. Это не конструктор («класс»), поэтому он одноразовый и жестко закодирован в элементе #VolumeSlider. Кроме того, из вашего кода это действительно не do все, что много. Кажется, это просто средний человек.

Вот альтернатива:

UserInterface = { 
    initialize: function() { 
    // Internal function to create a horizontal 0-100 slider 
    // Takes a selector, and a function that will receive the 
    // value of the slider 
    function buildSlider(selector, callback) { 
     var element = $(selector); 
     var handler = function (event, ui) { callback(ui.value); }; 
     element.slider({ 
     orientation: 'horizontal', 
     max: 100, 
     min: 0, 
     value: 0, 
     slide: handler, 
     change: handler 
     }); 
     return element; 
    } 

    // We probably want to bind the scope of setVolume, so use $.proxy 
    this.volumeSlider = buildSlider("#VolumeSlider", $.proxy(this.setVolume, this)); 

    // Want more sliders? Just add them 
    // this.speedSlider = buildSlider("#SpeedSlider", $.proxy(this.setSpeed, this)); 
    // this.balanceSlider = buildSlider("#BalanceSlider", $.proxy(this.setBalance, this)); 
    // etc... 
    }, 

    setVolume: function (value) { 
    if(value != 0) { 
     // not muted 
    } else { 
     // muted 
    } 
    } 
} 

С этим вполне может создать X количество ползунков для любых целей вам нужно. И нет отдельного одноразового объекта VolumeSlider; все обрабатывается в объекте UserInterface.

Конечно, это само по себе не может быть лучшей идеей, но для этой простой цели все в порядке. Однако вы можете извлечь buildSlider в более общий объект UIElements. Это может иметь методы, как buildSlider, buildButton и т.д.

В качестве альтернативы, вы могли бы пойти на «Ненавязчивый JavaScript» -WAY и имеют специальные имена классов и data- атрибутов, которые декларируют, как и где элемент помещается в пользовательском интерфейсе.Например

<div id="volumeSlider" class="ui-element" data-role="slider" data-action="setVolume">...

Может быть найдены вместе со всеми другими элементами пользовательского интерфейса с использованием $(".ui-element").each ..., после чего его атрибуты могут быть разобраны в виду, что это должно быть сделано в слайдер под названием «VolumeSlider», и его салазки/изменить события должны звонить setVolume ... Et cetera.

Опять же, многие, многие способы обойти это.

1

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

Если вам нужно больше, чем один регулятор громкости, просто изменить этот бит _volumeSlider: null, в _volumeSliders: [],

Если вам нужно ползунки по ссылке, инициализировать _volumeSliders к dict. Затем обратитесь к ним по номеру _volumeSliders[selector], и у вас есть свой объект.

Вместо функции для передачи значений вверх отправьте ссылку на родительский экземпляр вниз. Тогда вы можете написать parent.volume = value.

Как правило, я твердо придерживаюсь твердой, логичной, иерархической структуры. Никогда не изменяйте свою архитектуру, просто создавайте ссылки на область. В этом случае ссылка на родительскую область. Я бы не использовал метод первого ответчика, потому что мне, возможно, понадобится grep, чтобы найти источник создаваемых объектов.

У первого ответчика есть хорошие идеи. Вы можете заметить некоторые закономерности, которые повторяются, например. установка ссылки на элемент jQuery. Я обычно жду, пока не заметлю эти повторяющиеся шаблоны, а затем DRY с абстракцией, например. базовый класс, например, предложенный Фламбино, например, UIElement.

Смежные вопросы