model也是一個類,它定義了向用戶展現的屬性和數據行爲。model的定義很是簡單,只須要繼承DS.Model類便可,或者你也能夠直接使用Ember CLI命令建立。好比使用命令ember g model person定義了一個model類person。php
// app/models/person.js import DS from 'ember-data'; export default DS.Model.extend({ });
這個是個空的model,沒有定義任何屬性。有了model類你就可使用find方法查找數據了。數據庫
上面定義的model類person尚未任何屬性,下面爲這個類添加幾個屬性。服務器
// app/models/person.js import DS from 'ember-data'; export default DS.Model.extend({ firstName: DS.attr(), lastName: DS.attr(), birthday: DS.attr() });
上述代碼定義了3個屬性,可是還未給屬性指定類型,默認都是string類型。這些屬性名與你鏈接的服務器上的數據key是一致的。甚至你還能夠在model中定義計算屬性。數據結構
// app/models/person.js import DS from 'ember-data'; export default DS.Model.extend({ firstName: DS.attr(), lastName: DS.attr(), birthday: DS.attr(), fullName: Ember.computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; }) });
這段代碼在model類中定義了一個計算屬性fullName。app
前面定義的model類是沒有指定屬性類型的,默認狀況下都是string類型,顯然這是不夠的,簡單的model屬性類型包括:string,number,boolean,date。這幾個類型我想不用我解釋都應該知道了。函數
不只能夠指定屬性類型,你還能夠指定屬性的默認值,在attr()方法的第二個參數指定。好比下面的代碼:post
// app/models/person.js import DS from 'ember-data'; export default DS.Model.extend({ username: DS.attr('string'), email: DS.attr('string'), verified: DS.attr('boolean', { defaultValue: false }), //指定默認值是false // 使用函數返回值做爲默認值 createAt: DS.attr('string', { defaultValue(){ return new Date(); } }) });
正如代碼註釋所述的,設置默認值的方式包括直接指定或者是使用函數返回值指定。this
Ember的model也是有相似於數據庫的關聯關係的。只是相對於複製的數據庫Ember的model就顯得簡單不少,其中包括一對一,一對多,多對多關聯關係。這種關係是與後臺的數據庫是相統一的。spa
聲明一對一關聯使用DS.belongsTo設置。好比下面的兩個model。hibernate
// app/models/user.js import DS from 'ember-data'; export default DS.Model.extend({ profile: DS.belongsTo(‘profile’); });
// app/models/profile.js import DS from ‘ember-data’; export default DS.Model.extend({ user: DS.belongsTo(‘user’); });
聲明一對多關聯使用DS.belongsTo(多的一方使用)和DS.hasMany(少的一方使用)設置。好比下面的兩個model。
// app/models/post.js import DS from ‘ember-data’; export default DS.Model.extend({ comments: DS.hasMany(‘comment’); });
這個model是一的一方。下面的model是多的一方;
// app/models/comment.js import DS from ‘ember-data’; export default DS.Model.extend({ post: DS.belongsTo(‘post’); });
這種設置的方式與Java 的hibernate很是類似。
聲明一對多關聯使用DS.hasMany設置。好比下面的兩個model。
// app/models/post.js import DS from ‘ember-data’; export default DS.Model.extend({ tags: DS.hasMany(‘tag’); });
// app/model/tag.js import DS from ‘ember-data’; export default DS.Model.extend({ post: DS.hasMany(‘post’); });
多對多的關係設置都是使用hasMany,可是並不須要「中間表」,這個與數據的多對多有點不一樣,若是是數據的多對多一般是經過中間表關聯。
Ember Data會盡力去發現兩個model之間的關聯關係,好比前面的一對多關係中,當comment發生變化的時候會自動更新到post,由於每個comment只對應一個post,能夠有comment肯定到某個一個post。
然而,有時候同一個model中會有多個與此關聯model。這時你能夠在反向端用DS.hasMany的inverse選項指定其關聯的model:
// app/model/comment.js import DS from ‘ember-data’; export default DS.Model.extend({ onePost: DS.belongsTo(‘post’), twoPost: DS.belongsTo(‘post’), redPost: DS.belongsTo(‘post’), bluePost: DS.belongsTo(‘post’) });
在一個model中同時與3個post關聯了。
// app/models/post.js import DS from ‘ember-data’; export default DS.Model.extend({ comments: hasMany(‘comment’, { inverse: ‘redPost’ }); });
當comment發生變化時自動更新到redPost這個model。
當你想定義一個自反關係的model時(模型自己的一對一關係),你必需要顯式使用inverse指定關聯的model。若是沒有逆向關係則把inverse值設置爲null。
// app/models/folder.js import DS from ‘ember-data’; export default DS.Model.extend({ children: DS.hasMany(‘folder’, { reverse: ‘parent’ }); parent: DS.hasMany(‘folder’, { reverse: ‘children’ }); });
一個文件夾一般有父文件夾或者子文件夾。此時父文件夾和子文件夾與自己都是同一個類型的模型。此時你須要顯式使用inverse屬性指定,好比這段代碼所示,「children……」這行代碼意思是這個模型有一個屬性children,而且這個屬性也是一個folder,模型自己做爲父文件夾。同理「parent……」這行代碼的意思是這個模型有個屬性parent,而且這個屬性也是一個folder,模型自己是這個屬性的子文件夾。好比下圖結構:
這個有點像數據結構中的鏈表。你能夠把children和parent想象成是一個指針。
若是僅有關聯關係沒有逆向關係直接把inverse設置爲null。
// app/models/folder.js import DS from ‘ember-data’; export default DS.Model.extend({ parent: DS.belongsTo(‘folder’, { inverse: null }); });
// app/models/user.js import DS from ‘ember-data’; export default DS.Model.extend({ bestFriend: DS.belongsTo(‘folder’, { inverse: ‘bestFriend’ }); });
這個關係與數據庫設置設計中雙向一對一很相似。
有些model可能會包含深層嵌套的數據對象,若是也是使用上述的關聯關係定義那麼將是個噩夢!對於這種狀況最好是把數據定義成簡單對象,雖然增長點冗餘數據可是下降了層次。另一種是把嵌套的數據定義成model的屬性(也是增長冗餘可是下降了嵌套層次)。