Ember JS - 组件与工厂

时间:2016-04-25 23:44:08

标签: ember.js

我是Ember JS的新手,我甚至不得不承认这是我使用的第一个框架。

好。我正面临设计问题。我想创建一个音频网络应用程序,它将始终需要能够播放音频,因此我想制作一个AudioPlayer单例,它将在应用程序的整个生命周期内提供。

根据Ember关于Dependency Injection的文档,我可以注册 factory ,默认情况下注册为singleton,我可以通过以下方式访问它:

applicationInstance.lookup('audio:player'); // For example

这似乎是一个想法,但我还需要一个音频播放器的界面,有旋钮,如播放,暂停和停止;是的HTML。那可能吗?为工厂制作一个“视图”?

我看到的第二种可能性是制作一个audio-player 组件,但是我必须放弃组件,我只想在网站上只有一个音频播放器,也将是AudioContext的所有者,每个网站只需要一次。

因此。我该怎么办?我应该去工厂还是模特?

PS:我想我需要一个控制器,但我已经在Ember JS指南中读到它很快就会被弃用。

1 个答案:

答案 0 :(得分:3)

我很快为你实现了一些东西,扩展了@Deewendra的评论。您会看到该应用程序包含两个前面提到的部分。

服务目录中的音频播放器服务

export default Ember.Service.extend({
  ids: [0,1,2,3,4,5,6,7,8,9,10],
  songs: Ember.computed('ids',function(){
    return this.get('ids').map(id => {
        return { id: id, title: `Awesome Song ${id}`}
    })
  }),
  currentlyPlaying: '',
  currentIndex: 0,
  currentStatus: 'stopped',

  start() {
    this.setSongByIndex();
    this.set('currentStatus','playing');
  },
  stop(){
    this.set('currentStatus','stopped');
  },
  nextSong() {
    let maxIndex = this.get('ids.length') - 1;
    let currentIndex = this.get('currentIndex');
    let nextIndex = currentIndex + 1;

    if (nextIndex > maxIndex) {
        this.stop();
    } else {
        this.set('currentIndex',nextIndex);
        this.setSongByIndex();
    }
  },
  previousSong() {
    let maxIndex = this.get('ids.length') - 1;
    let currentIndex = this.get('currentIndex');
    let prevIndex = currentIndex - 1;

    if (prevIndex < 0) {
        this.stop();
    } else {
        this.set('currentIndex',prevIndex);
        this.setSongByIndex();
    }
  },
  setSongByIndex() {
    const songs = this.get('songs');
    const currentIndex = this.get('currentIndex');
    this.set('currentlyPlaying',songs[currentIndex]);
  }
});

音频播放器组件

// components/audio-player.js
export default Ember.Component.extend({
  audioPlayer: Ember.inject.service('audio-player'),
  actions: {
    start() {
        this.get('audioPlayer').start();
    },
    stop() {
        this.get('audioPlayer').stop();
    },
    next(){
        this.get('audioPlayer').nextSong();
    },
    previous(){
        this.get('audioPlayer').previousSong();
    }
  }
});

// templates/components/audio-player
Song Title: {{audioPlayer.currentlyPlaying.title}} <br/>
Audio Player Status: {{audioPlayer.currentStatus}} <br/>
<button {{action 'start'}}>Start</button> |
<button {{action 'next'}}>Next</button> |
<button {{action 'previous'}}>Previous</button> |
<button {{action 'stop'}}>Stop</button> |

使用Ember.inject.service()方法连接到服务。

正如您将看到的,播放器的“状态”存在于服务中,组件通过html / handlebars模板与其交互,并附带相当于模板名称的javascript文件,将处理“视图”(模板)和“状态”(服务)之间的交互。

这是twiddle点击进入并进行实验。

我不确定你在“框架”以外的编程方面有什么经验,关于网络技术等,并且在提交这个问题时要三思而后行,但我认为它应该有所帮助而不是它会受到伤害。