2016-04-25 83 views
0

我對Ember JS很新,我甚至不得不承認這是我第一個使用的框架。Ember JS - 組件vs.工廠

好吧。我正面臨設計問題。我想製作一個音頻網絡應用程序,它總是需要能夠播放音頻,因此我想製作一個AudioPlayer單身人士,這個單身人士可以在應用程序的整個生命週期中使用。

據Ember的上Dependency Injection文檔我可以只註冊一個工廠,在默認情況下被註冊爲單身,我可以通過所有的時間訪問:

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

這似乎是一個想法,但我也需要一個音頻播放器的接口,帶有播放,暫停和停止等旋鈕; HTML是。那可能嗎?爲工廠做一個「觀點」?

我看到的第二個可能性是使一個audio-player組件,但與組件我不得不放棄單身了,我真的只希望自己的網站,這也將是AudioContext的船東,只是一個audioplayer ,每個網站只需要一次。

所以。我該怎麼辦?我應該去工廠還是與模型?


PS:我想認爲我需要一個控制器,但我已經灰燼JS指南,這是很快就被棄用讀取。

+1

一個選項是你仍然可以使用提供UI的組件,並且這個組件可以使用包含所有核心功能的audioPlayer服務,並且服務默認爲singleton。(https://guides.emberjs.com/ v2.5.0/applications/services /) –

回答

2

我很快爲您實施了一些東西,它擴展了@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]); 
    } 
}); 

其是通過使用Ember.inject.service()方法連接到服務的音頻播放器組件

// 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> | 

的音頻播放器的服務。如你所見,玩家的「狀態」存在於服務中,並且組件通過html/handlebars模板與其交互,並與一個與該模板名稱相當的JavaScript文件相結合,這將會處理「視圖」(模板)和「狀態」(服務)之間的交互。

這是一個twiddle點擊進去,並進行實驗。

我不確定你的經驗是關於「框架」之外的編程方面的,關於網絡技術等方面的問題,並且提交過這個問題想過兩次,但我認爲它應該比它受到的傷害更大。

+0

我還沒有真正意識到服務。非常感謝你! – Tomasito665

+0

我建議在'init'方法中初始化屬性,特別是數組和對象。在這種情況下,這不是一個問題,因爲服務是單身人士,但這是一個很好的做法。 – locks