在上传歌曲的时候, 我们将歌曲名/歌手/外链会填入表单. 当我们点击保存时, 页面左侧的歌曲列表变回多出一首歌, 同时, 歌曲会保存在leanCloud的项目中.
可以把它抽象为发布订阅模式, 左侧的歌曲列表和将歌曲保存在leanCloud项目这一动作都是订阅者. 发布者就是提交表单这一动作.
创建eventHub.js
我们创建./js/eventHub.js
:
window.eventHub = {
events: {},
emit(eventName, data) {
for (let key in this.events) {
if (key === eventName) {
let fnList = this.events[key]
fnList.map((fn)=>{
fn.call(undefined, data)
})
}
}
},
on(eventName, fn) {
if (this.events[eventName] === undefined) {
this.events[eventName] = []
}
this.events[eventName].push(fn)
}
}
在这个文件中, 我们定义了events对象, 用于存放每个事件的订阅者. emit用于触发事件. on用来对events中的事件添加订阅者.
song-form.js
admin.html中有个表单, 表单的数据我们在model中表示:
let model = {
data: {
name: '', singer:'', url:'', id:''
},
create(data) {
// 声明类型
var Song = AV.Object.extend('Song');
// 新建对象
var song = new Song();
// 设置名称
song.set('name', data.name);
song.set('singer', data.singer);
song.set('url', data.url);
return song.save().then((newSong) =>{
let {id , attributes} = newSong
Object.assign(this.data, {id, ...attributes})
}, (error)=> {
console.error(error);
});
}
}
其中create中的代码有leanCloud官方文档提供.
同时在controller加入bindEvents事件:
bindEvents() {
this.view.$el.on('submit', 'form', (e)=>{
e.preventDefault()
let needs = 'name singer url'.split(' ')
let data = {}
needs.map((string)=>{
data[string] = this.view.$el.find(`[name="${string}"]`).val()
})
this.model.create(data)
.then(()=>{
this.view.reset()
let string = JSON.stringify(this.model.data)
let object = JSON.parse(string)
window.eventHub.emit('create', object)
})
})
}
注意当执行create(data)成功后, 订阅者会触发create事件
最后, 在song-form.js中的controller中加入如下代码:
window.eventHub.on('upload', (data)=>{
this.model.data = data
this.view.render(this.model.data)
})
我们在发布者中注册upload事件, 这样当表单提交时, 会重新渲染页面
song-list.js
这个文件是加载歌曲列表的. 我们在controller中加入如下代码:
window.eventHub.on('upload', ()=>{
this.view.clearActive()
})
window.eventHub.on('create', (songData)=>{
this.model.data.songs.push(songData)
this.view.render(this.model.data)
})
model中只有一个data对象:
let model = {
data: {
songs: []
}
}
重新写下render函数:
render(data) {
let $el = $(this.el)
$el.html(this.template)
let {songs} = data
let liList = songs.map((song)=>$('<li></li>').text(song.name))
$el.find('ul').empty()
liList.map((domLi)=>{
$el.find('ul').append(domLi)
})
}
new-song.js
这个文件只是新建歌曲四个字.
window.eventHub.on('upload', (data)=>{
this.active() //添加css的active类
})
upload-song.js
这个文件管理着上传时候的动作. 在上传成功后触发upload事件
'FileUploaded': function(up, file, info) {
window.eventHub.emit('upload', {
url: sourceLink,
name: response.key
})
}