Ember.js 入門指南——定義模型

model也是一個類,它定義了向用戶展現的屬性和數據行爲。model的定義很是簡單,只須要繼承DS.Model類便可,或者你也能夠直接使用Ember CLI命令建立。好比使用命令ember g model person定義了一個modelpersonphp

//  app/models/person.js
 
import DS from 'ember-data';
 
export default DS.Model.extend({
 
});

這個是個空的model,沒有定義任何屬性。有了model類你就可使用find方法查找數據了。數據庫

 

1,定義屬性

       上面定義的modelperson尚未任何屬性,下面爲這個類添加幾個屬性。服務器

//  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類中定義了一個計算屬性fullNameapp

2,指定屬性類型與默認值

       前面定義的model類是沒有指定屬性類型的,默認狀況下都是string類型,顯然這是不夠的,簡單的model屬性類型包括:stringnumberbooleandate。這幾個類型我想不用我解釋都應該知道了。函數

       不只能夠指定屬性類型,你還能夠指定屬性的默認值,在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

 

3,定義model的關聯關係

       Embermodel也是有相似於數據庫的關聯關係的。只是相對於複製的數據庫Embermodel就顯得簡單不少,其中包括一對一,一對多,多對多關聯關係。這種關係是與後臺的數據庫是相統一的。spa

1,一對一

       聲明一對一關聯使用DS.belongsTo設置。好比下面的兩個modelhibernate

//  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’);
});

 

2,一對多

       聲明一對多關聯使用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很是類似。

3,多對多

聲明一對多關聯使用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,可是並不須要中間表,這個與數據的多對多有點不一樣,若是是數據的多對多一般是經過中間表關聯。

 

4,顯示反轉

       Ember Data會盡力去發現兩個model之間的關聯關係,好比前面的一對多關係中,當comment發生變化的時候會自動更新到post,由於每個comment只對應一個post,能夠有comment肯定到某個一個post

       然而,有時候同一個model中會有多個與此關聯model。這時你能夠在反向端用DS.hasManyinverse選項指定其關聯的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中同時與3post關聯了。

//  app/models/post.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  comments: hasMany(‘comment’, { inverse: ‘redPost’ });
});

       comment發生變化時自動更新到redPost這個model

 

5,自反關係

1,一對多

當你想定義一個自反關係的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,模型自己是這個屬性的子文件夾。好比下圖結構:

這個有點像數據結構中的鏈表。你能夠把childrenparent想象成是一個指針。

       若是僅有關聯關係沒有逆向關係直接把inverse設置爲null

//  app/models/folder.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  parent: DS.belongsTo(‘folder’, { inverse: null });
});
2,一對一
//  app/models/user.js
import DS from ‘ember-data’;
export default DS.Model.extend({
  bestFriend: DS.belongsTo(‘folder’, { inverse: ‘bestFriend’ });
});

       這個關係與數據庫設置設計中雙向一對一很相似。

 

6,嵌套數據

       有些model可能會包含深層嵌套的數據對象,若是也是使用上述的關聯關係定義那麼將是個噩夢!對於這種狀況最好是把數據定義成簡單對象,雖然增長點冗餘數據可是下降了層次。另一種是把嵌套的數據定義成model的屬性(也是增長冗餘可是下降了嵌套層次)。

相關文章
相關標籤/搜索