Ember 新建、更新、刪除記錄

2018-01-06 18:00 更新

前一篇介紹了查詢方法,本篇介紹新建、更新、刪除記錄的方法。 本篇的示例代碼創(chuàng)建在上一篇的基礎(chǔ)上。對(duì)于整合firebase、創(chuàng)建routetemplate請(qǐng)參看上一篇,增加一個(gè)controller:ember g controller articles。

1,新建記錄

創(chuàng)建新的記錄使用createRecord()方法。比如下面的代碼新建了一個(gè)aritcle記錄。修改模板,在模板上增加幾個(gè)input輸入框用于輸入article信息。

  1. <div class="container">
  2. <div class="row">
  3. <div class="col-md-4 col-xs-4">
  4. <ul class="list-group">
  5. {{#each model as |item|}}
  6. <li class="list-group-item">
  7. {{#link-to 'articles.article' item.id}}
  8. {{item.title}} -- <small>{{item.category}}</small>
  9. {{/link-to}}
  10. </li>
  11. {{/each}}
  12. </ul>
  13. <div>
  14. title:{{input value=title}}<br>
  15. body: {{textarea value=body cols="80" rows="3"}}<br>
  16. category: {{input value=category}}<br>
  17. <button {{ action "saveItem"}}>保存</button>
  18. <font color='red'>{{tipInfo}}</font>
  19. </div>
  20. </div>
  21. <div class="col-md-8 col-xs-8">
  22. {{outlet}}
  23. </div>
  24. </div>
  25. </div>

頁(yè)面的字段分別對(duì)應(yīng)這模型article的屬性。點(diǎn)擊“保存”后提交到controller處理。下面是獲取數(shù)據(jù)保存數(shù)據(jù)的controller。

  1. // app/controllers/articles.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. actions: {
  5. // 表單提交,保存數(shù)據(jù)到Store。Store會(huì)自動(dòng)更新到firebase
  6. saveItem: function() {
  7. var title = this.get('title');
  8. if ('undefined' === typeof(title) || '' === title.trim()) {
  9. this.set('tipInfo', "title不能為空");
  10. return ;
  11. }
  12. var body = this.get('body');
  13. if ('undefined' === typeof(body) || '' === body.trim()) {
  14. this.set('tipInfo', "body不能為空");
  15. return ;
  16. }
  17. var category = this.get('category');
  18. if ('undefined' === typeof(category) || '' === category.trim()) {
  19. this.set('tipInfo', "category不能為空");
  20. return ;
  21. }
  22. // 創(chuàng)建數(shù)據(jù)記錄
  23. var article = this.store.createRecord('article', {
  24. title: title,
  25. body: body,
  26. category: category,
  27. timestamp: new Date().getTime()
  28. });
  29. article.save(); //保存數(shù)據(jù)的到Store
  30. // 清空頁(yè)面的input輸入框
  31. this.set('title', "");
  32. this.set('body', "");
  33. this.set('category', "");
  34. }
  35. }
  36. });

主要看createRecord方法,第一個(gè)參數(shù)是模型名稱。第二個(gè)參數(shù)是個(gè)哈希,在哈??傇O(shè)置模型屬性值。最后調(diào)用article.save()方法把數(shù)據(jù)保存到Store,再由Store保存到firebase。運(yùn)行效果如下圖:

結(jié)果截圖

輸入信息,點(diǎn)擊“保存”后數(shù)據(jù)立刻會(huì)顯示在列表”no form -- java”之后。然后你可以點(diǎn)擊標(biāo)題查詢?cè)敿?xì)信息,body的信息會(huì)在頁(yè)面后側(cè)顯示。

通過(guò)這里實(shí)例我想你應(yīng)該懂得去使用createRecord()方法了!但是如果有兩個(gè)模型是有關(guān)聯(lián)關(guān)系保存的方法又是怎么樣的呢?下面再新增一個(gè)模型。

  1. ember g model users

然后在模型中增加關(guān)聯(lián)。

  1. // app/models/article.js
  2. import DS from 'ember-data';
  3. export default DS.Model.extend({
  4. title: DS.attr('string'),
  5. body: DS.attr('string'),
  6. timestamp: DS.attr('number'),
  7. category: DS.attr('string'),
  8. author: DS.belongsTo('user') //關(guān)聯(lián)user
  9. });
  10. // app/models/user.js
  11. import DS from 'ember-data';
  12. export default DS.Model.extend({
  13. username: DS.attr('string'),
  14. timestamp: DS.attr('number'),
  15. articles: DS.hasMany('article') //關(guān)聯(lián)article
  16. });

修改模板articles.hbs在界面上增加錄入作者信息字段。

  1. ……省略其他代碼
  2. <div>
  3. title:{{input value=title}}<br>
  4. body: {{textarea value=body cols="80" rows="3"}}<br>
  5. category: {{input value=category}}<br>
  6. <br>
  7. author: {{input value=username}}<br>
  8. <button {{ action "saveItem"}}>保存</button>
  9. <font color='red'>{{tipInfo}}</font>
  10. </div>
  11. ……省略其他代碼

下面看看怎么在controller中設(shè)置這兩個(gè)模型的關(guān)聯(lián)關(guān)系。一共有兩種方式設(shè)置,一種是直接在createRecord()方法中設(shè)置,另一種是在方法外設(shè)置。

  1. // app/controllers/articles.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. actions: {
  5. // 表單提交,保存數(shù)據(jù)到Store。Store會(huì)自動(dòng)更新到firebase
  6. saveItem: function() {
  7. // 獲取信息和校驗(yàn)代碼省略……
  8. // 創(chuàng)建user
  9. var user = this.store.createRecord('user', {
  10. username: username,
  11. timestamp: new Date().getTime()
  12. });
  13. // 必須要執(zhí)行這句代碼,否則user數(shù)據(jù)不能保存到Store,
  14. // 否則article通過(guò)user的id查找不到user
  15. user.save();
  16. // 創(chuàng)建article
  17. var article = this.store.createRecord('article', {
  18. title: title,
  19. body: body,
  20. category: category,
  21. timestamp: new Date().getTime(),
  22. author: user //設(shè)置關(guān)聯(lián)
  23. });
  24. article.save(); //保存數(shù)據(jù)的到Store
  25. // 清空頁(yè)面的input輸入框
  26. this.set('title', "");
  27. this.set('body', "");
  28. this.set('category', "");
  29. this.set('username', "");
  30. }
  31. }
  32. });

界面截圖

輸入上如所示信息,點(diǎn)擊“保存”可以在firebase的后臺(tái)看到如下的數(shù)據(jù)關(guān)聯(lián)關(guān)系。

firebase數(shù)據(jù)截圖

注意點(diǎn):與這兩個(gè)數(shù)據(jù)的關(guān)聯(lián)是通過(guò)數(shù)據(jù)的id維護(hù)的。 那么如果我要通過(guò)article獲取user的信息要怎么獲取呢?

直接以面向?qū)ο蟮姆绞将@取既可。

  1. {{#each model as |item|}}
  2. <li class="list-group-item">
  3. {{#link-to 'articles.article' item.id}}
  4. {{item.title}} -- <small>{{item.category}}</small> -- <small>{{item.author.username}}</small>
  5. {{/link-to}}
  6. </li>
  7. {{/each}}

注意看助手{{ item.author.username }}。很像EL表達(dá)式吧??! 前面提到過(guò)有兩個(gè)方式設(shè)置兩個(gè)模型的關(guān)聯(lián)關(guān)系。下面的代碼是第二種方式:

  1. // 其他代碼省略……
  2. // 創(chuàng)建article
  3. var article = this.store.createRecord('article', {
  4. title: title,
  5. body: body,
  6. category: category,
  7. timestamp: new Date().getTime()
  8. // ,
  9. // author: user //設(shè)置關(guān)聯(lián)
  10. });
  11. // 第二種設(shè)置關(guān)聯(lián)關(guān)系方法,在外部手動(dòng)調(diào)用set方法設(shè)置
  12. article.set('author', user);
  13. // 其他代碼省略……

運(yùn)行,重新錄入信息,得到的結(jié)果是一致的。甚至你可以直接在createRecord方法里調(diào)用方法來(lái)設(shè)置兩個(gè)模型的關(guān)系。比如下面的代碼段:

  1. var store = this.store; // 由于作用域問(wèn)題,在createRecord方法內(nèi)部不能使用this.store
  2. var article = this.store.createRecord('article', {
  3. title: title,
  4. // ……
  5. // ,
  6. // author: store.findRecord('user', 1) //設(shè)置關(guān)聯(lián)
  7. });
  8. // 第二種設(shè)置關(guān)聯(lián)關(guān)系方法,在外部手動(dòng)調(diào)用set方法設(shè)置
  9. article.set('author', store.findRecord('user', 1));

這種方式可以直接動(dòng)態(tài)根據(jù)user的id屬性值獲取到記錄,再設(shè)置關(guān)聯(lián)關(guān)系。新增介紹完了,接著介紹記錄的更新。

2,更新記錄

更新相對(duì)于新增來(lái)說(shuō)非常相似。請(qǐng)看下面的代碼段: 首先在模板上增加更新的設(shè)置代碼,修改子模板articles/article.hbs

  1. <h2>{{model.title}}</h2>
  2. <div class = "body">
  3. {{model.body}}
  4. </div>
  5. <div>
  6. <br><hr>
  7. 更新測(cè)試<br>
  8. title: {{input value=model.title}}<br>
  9. body:<br> {{textarea value=model.body cols="80" rows="3"}}<br>
  10. <button {{action 'updateArticleById' model.id}}>更新文章信息</button>
  11. </div>

增加一個(gè)controller,用戶處理子模板提交的修改信息。

  1. ember g controller articles/article
  1. // app/controllers/articles/article.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. actions: {
  5. // 根據(jù)文章id更新
  6. updateArticleById: function(params) {
  7. var title = this.get('model.title');
  8. var body = this.get('model.body');
  9. this.store.findRecord('article', params).then(function(art) {
  10. art.set('title', title);
  11. art.set('body', body);
  12. // 保存更新的值到Store
  13. art.save();
  14. });
  15. }
  16. }
  17. });

在左側(cè)選擇需要更新的數(shù)據(jù),然后在右側(cè)輸入框中修改需要更新的數(shù)據(jù),在修改過(guò)程中可以看到被修改的信息會(huì)立即反應(yīng)到界面上,這個(gè)是因?yàn)镋mber自動(dòng)更新Store中的數(shù)據(jù)(還記得很久前講過(guò)的觀察者(observer)嗎?)。

結(jié)果截圖

如果你沒(méi)有點(diǎn)擊“更新文章信息”提交,你修改的信息不會(huì)更新到firebase。頁(yè)面刷新后還是原來(lái)樣子,如果你點(diǎn)擊了“更新文章信息”數(shù)據(jù)將會(huì)把更新的信息提交到firebase。

由于save、findRecord方法返回值是一個(gè)promises對(duì)象,所以你還可以針對(duì)出錯(cuò)情況進(jìn)行處理。比如下面的代碼:

  1. var user = this.store.createRecord('user', {
  2. // ……
  3. });
  4. user.save().then(function(fulfill) {
  5. // 保存成功
  6. }).catch(function(error) {
  7. // 保存失敗
  8. });
  9. this.store.findRecord('article', params).then(function(art) {
  10. // ……
  11. }).catch(function(error) {
  12. // 出錯(cuò)處理代碼
  13. });

具體代碼我就不演示了,請(qǐng)讀者自己編寫(xiě)測(cè)試吧?。?/p>

3,刪除記錄

既然有了新增那么通常就會(huì)有刪除。記錄的刪除與修改非常類(lèi)似,也是首先查詢出要?jiǎng)h除的數(shù)據(jù),然后執(zhí)行刪除。

  1. // app/controllers/articles.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. actions: {
  5. // 表單提交,保存數(shù)據(jù)到Store。Store會(huì)自動(dòng)更新到firebase
  6. saveItem: function() {
  7. // 省略
  8. },
  9. // 根據(jù)id屬性值刪除數(shù)據(jù)
  10. delById : function(params) {
  11. // 任意獲取一個(gè)作為判斷表單輸入值
  12. if (params && confirm("你確定要?jiǎng)h除這條數(shù)據(jù)嗎??")) {
  13. // 執(zhí)行刪除
  14. this.store.findRecord('article', params).then(function(art) {
  15. art.destroyRecord();
  16. alert('刪除成功!');
  17. }, function(error) {
  18. alert('刪除失??!');
  19. });
  20. } else {
  21. return;
  22. }
  23. }
  24. }
  25. });

修改顯示數(shù)據(jù)的模板,增加刪除按鈕,并傳遞數(shù)據(jù)的id值到controller

  1. <div class="container">
  2. <div class="row">
  3. <div class="col-md-4 col-xs-4">
  4. <ul class="list-group">
  5. {{#each model as |item|}}
  6. <li class="list-group-item">
  7. {{#link-to 'articles.article' item.id}}
  8. {{item.title}} -- <small>{{item.category}}</small> -- <small>{{item.author.username}}</small>
  9. {{/link-to}}
  10. <button {{action 'delById' item.id}}>刪除</button>
  11. </li>
  12. {{/each}}
  13. </ul>
  14. // ……省略其他代碼
  15. </div>
  16. </div>

截圖

結(jié)果如上圖,點(diǎn)擊第二條數(shù)據(jù)刪除按鈕。彈出提示窗口,點(diǎn)擊“確定”之后成功刪除數(shù)據(jù),并彈出“刪除成功!”,到firebase后臺(tái)查看數(shù)據(jù),確實(shí)已經(jīng)刪除成功。 然而與此關(guān)聯(lián)的user卻沒(méi)有刪除,正常情況下也應(yīng)該是不刪除關(guān)聯(lián)的user數(shù)據(jù)的。 最終結(jié)果只剩下一條數(shù)據(jù):

截圖

到此,有關(guān)新增、更新、刪除的方法介紹完畢。已經(jīng)給出了詳細(xì)的演示實(shí)例,我相信,如果你也親自在自己的項(xiàng)目中實(shí)踐過(guò),那么掌握這幾個(gè)方法是很容易的!
博文完整代碼放在Github(博文經(jīng)過(guò)多次修改,博文上的代碼與github代碼可能有出入,不過(guò)影響不大?。?,如果你覺(jué)得博文對(duì)你有點(diǎn)用,請(qǐng)?jiān)趃ithub項(xiàng)目上給我點(diǎn)個(gè)star吧。您的肯定對(duì)我來(lái)說(shuō)是最大的動(dòng)力??!

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)