Ember.js - 触发控制器外的属性

时间:2014-06-30 21:35:05

标签: 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 && 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设置为主播放/暂停按钮并调用操作,以便当我单击主暂停/播放按钮时,它将找到特定的歌曲并在点击时播放。

3 个答案:

答案 0 :(得分:1)

你需要:

  • 包装主按钮和个别歌曲的模板
  • 将处理各个歌曲事件和状态的组件
    • 从这里开始处理向上传播的个别歌曲事件
  • 事件从组件冒泡到模板控制器
    • 模板控制器会收到组件事件通知
    • 在这里您可以更新主控件
  • 通过绑定处理播放/停止消息

工作示例:http://emberjs.jsbin.com/dopoho/1/edit?html,js,console,output

我应该使用数组控制器作为歌曲列表,我确信有一些我没有考虑过的用例。重点是向您展示如何使用组件重用代码以及如何将事件从模板传递到组件再传递给控制器​​。

答案 1 :(得分:1)

您无需更改各个播放按钮的操作。仅限全局按钮。

如此更新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。如果您想使用全局按钮重新启动歌曲,它还知道要使用哪首曲目......

这只是第一步,我并不想为你编写整个代码。此时您真正需要做的就是在把手上进行一些重构并更新全局按钮上的操作。

你也可以在某种模板中使用currentTrack,每当你改变音轨时它总是会重新渲染。非常酷的Ember-tastic东西。

祝你好运!

答案 2 :(得分:-1)

您可以创建控制器对象的层次结构,如下所示:

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

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

有了这个,您可以在Base控制器中放置所有播放暂停功能,并通过基本身(或子控制器根据您的需要)中的操作切换它们。

希望这是有道理的。