Ember.js — Запуск свойств вне контроллера

#ember.js #handlebars.js

#ember.js #handlebars.js

Вопрос:

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

У меня есть следующий код

 Tracks.TrackController = Ember.ObjectController.extend({
  currentTime: 0,
  isLoaded: false,
  isPlaying:false,
  songStarted:false,

  actions: {

     play: function(){
        var track_id = this.id;
        var mySound = soundManager.createSound({
          id: track_id,
          url: 'https://api.soundcloud.com/tracks/'   track_id   '/stream?client_id=d61f17a08f86bfb1dea28539908bc9bf',
          autoplay: false,
          whileplaying: function() {
                $('#positionBar').css('width', ((this.position/this.duration) * 100)   '%'); 
            },
         });

         songStarted:true;
         this.set("isPlaying", true);
         this.set('mySound', mySound);
         soundManager.stopAll();
         mySound.play();

     },

     pause: function(){
        var mySound = this.get('mySound');
        this.set("isPlaying", false);
        this.set("isPaused", true);
        if(mySound amp;amp; mySound.pause){
           mySound.pause(); 
        }
     },

     resume: function(){
        var mySound = this.get('mySound');
        this.set("isPlaying", true);
        this.set("isPaused", false);
        mySound.resume(); 
      }
   }
});
  

и это как разметка:

 {{#if isPlaying}}
        <li class="playBtn pause"><button {{action 'pause' this}} class="play-btn sm2_button" id="masterPlayBtn"></button></li>
{{else}}
    {{#if isPaused}}
        <li class="playBtn"><button {{action 'resume' this}} class="play-btn sm2_button" id="masterPlayBtn"></button></li>
    {{else}}
        <li class="playBtn"><button {{action 'play' this}} class="play-btn sm2_button" id="masterPlayBtn"></button></li>
    {{/if}}
{{/if}}
  

Я предполагаю, что мне нужно добавить действия в

    Tracks.TracksController = Ember.ArrayController.extend({

   }); 
  

контроллер, но вот где я заблудился. Кажется, я не могу понять, как установить isPlaying на главную кнопку воспроизведения / паузы, а также вызвать действия, чтобы, когда я нажимаю главную кнопку паузы / воспроизведения, она находила конкретную песню и воспроизводила ее по щелчку.

Ответ №1:

Вам нужно:

  • Шаблон, который переносит главную кнопку и отдельные композиции
  • Компонент, который будет обрабатывать отдельные песни, события и состояния
    • отсюда вы обрабатываете отдельные события песни, которые распространяются вверх
  • Передача событий из компонентов в контроллер шаблона
    • контроллер шаблона уведомляется о событиях компонента
    • здесь вы можете обновить главный элемент управления
  • Обрабатывать сообщения воспроизведения / остановки через привязки

Рабочий пример:http://emberjs.jsbin.com/dopoho/1/edit?html ,js, консоль, вывод

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

Ответ №2:

Вам не нужно изменять действия на отдельных кнопках воспроизведения. Только на глобальной кнопке.

Обновите TracksController таким образом:

 Tracks.TracksController = Ember.ArrayController.extend({
  restartTrack: null, // Need to restart with the global button? Use my model!

  currentTrack: function () {
    var filtered = this.get('content').filter(function (track) {
      return this.get('isPlaying');
    });
    if(Ember.isEmpty(filtered)){
      return null;
    }
    var track = filtered.objectAt(0);
    this.set('restartTrack', track); // Should be on the item action...
    return track;
  }.property('@each.isPlaying'),

  isPlaying: function () {
    return this.get('content').any(function (track) {
      return this.get('isPlaying');
    });
  }.property('@each.isPlaying')
}); 
  

Так что теперь ваш TracksController всегда знает, изменилась ли песня индивидуально, и изменит свою собственную isPlaying . Он также знает, какой трек использовать, если вы хотите перезапустить песню с помощью глобальной кнопки…

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

Вы также можете использовать currentTrack в каком-то шаблоне, и он всегда будет повторно отображаться всякий раз, когда вы меняете трек. Довольно классная штука на вкус.

Удачи!

Ответ №3:

Вы могли бы создать иерархию объектов контроллера, как показано ниже:

 Tracks.BaseTrackController = Ember.ObjectController.extend({...});

Tracks.TrackController = Tracks.BaseTrackController.extend({...});
  

При этом вы могли бы разместить все функции приостановки воспроизведения в базовом контроллере и переключать их с помощью действий в самой базе (или дочернем контроллере в зависимости от ваших потребностей)

Надеюсь, это имеет смысл.