Ember.js 入門指南——新建、更新、刪除記錄
前一篇介紹了查詢方法,本篇介紹新建、更新、刪除記錄的方法。
本篇的示例程式碼建立在上一篇的基礎上。對於整合firebase、建立route和template請參看上一篇,增加一個controller:ember g controller articles。
1,新建記錄
建立新的記錄使用createRecord()方法。比如下面的程式碼新建了一個aritcle記錄。修改模板,在模板上增加幾個input輸入框用於輸入article資訊。
<!-- app/templates/articles.hbs --> <div> <div> <div class="col-md-4 col-xs-4"> <ul> {{#each model as |item|}} <li> <!--設定路由,路由的層級與router.js裡定義的要一致 --> {{#link-to 'articles.article' item.id}} {{item.title}} -- <small>{{item.category}}</small> {{/link-to}} </li> {{/each}} </ul> <div> title:{{input value=title}}<br> body: {{textarea value=body cols="80" rows="3"}}<br> category: {{input value=category}}<br> <button {{ action "saveItem"}}>儲存</button> <font color='red'>{{tipInfo}}</font> </div> </div> <div class="col-md-8 col-xs-8"> {{outlet}} </div> </div> </div>
頁面的欄位分別對應這模型article的屬性。點選“儲存”後提交到controller處理。下面是獲取資料儲存資料的controller。
// app/controllers/articles.js import Ember from 'ember'; export default Ember.Controller.extend({ actions: { // 表單提交,儲存資料到Store。Store會自動更新到firebase saveItem: function() { var title = this.get('title'); if ('undefined' === typeof(title) || '' === title.trim()) { this.set('tipInfo', "title不能為空"); return ; } var body = this.get('body'); if ('undefined' === typeof(body) || '' === body.trim()) { this.set('tipInfo', "body不能為空"); return ; } var category = this.get('category'); if ('undefined' === typeof(category) || '' === category.trim()) { this.set('tipInfo', "category不能為空"); return ; } // 建立資料記錄 var article = this.store.createRecord('article', { title: title, body: body, category: category, timestamp: new Date().getTime() }); article.save(); //儲存資料的到Store // 清空頁面的input輸入框 this.set('title', ""); this.set('body', ""); this.set('category', ""); } } });
主要看createRecord方法,第一個引數是模型名稱。第二個引數是個雜湊,在雜湊總設定模型屬性值。最後呼叫article.save()方法把資料儲存到Store,再由Store儲存到firebase。執行效果如下圖:
輸入資訊,點選“儲存”後資料立刻會顯示在列表”no form -- java”之後。然後你可以點選標題查詢詳細資訊,body的資訊會在頁面後側顯示。
通過這裡例項我想你應該懂得去使用createRecord()方法了!
但是如果有兩個model是有關聯關係儲存的方法又是怎麼樣的呢?下面再新增一個model。
ember g model users
然後在model中增加關聯。
// app/models/article.js import DS from 'ember-data'; export default DS.Model.extend({ title: DS.attr('string'), body: DS.attr('string'), timestamp: DS.attr('number'), category: DS.attr('string'), author: DS.belongsTo('user') //關聯user });
// app/models/user.js import DS from 'ember-data'; export default DS.Model.extend({ username: DS.attr('string'), timestamp: DS.attr('number'), articles: DS.hasMany('article') //關聯article });
修改模板articles.hbs在介面上增加錄入作者資訊欄位。
……省略其他程式碼 <div> title:{{input value=title}}<br> body: {{textarea value=body cols="80" rows="3"}}<br> category: {{input value=category}}<br> <br> author: {{input value=username}}<br> <button {{ action "saveItem"}}>儲存</button> <font color='red'>{{tipInfo}}</font> </div> ……省略其他程式碼
下面看看怎麼在controller中設定這兩個model的關聯關係。一共有兩種方式設定,一種是直接在createRecord()方法中設定,另一種是在方法外設定。
// app/controllers/articles.js import Ember from 'ember'; export default Ember.Controller.extend({ actions: { // 表單提交,儲存資料到Store。Store會自動更新到firebase saveItem: function() { // 獲取資訊和校驗程式碼省略…… // 建立user var user = this.store.createRecord('user', { username: username, timestamp: new Date().getTime() }); // 必須要執行這句程式碼,否則user資料不能儲存到Store, // 否則article通過user的id查詢不到user user.save(); // 建立article var article = this.store.createRecord('article', { title: title, body: body, category: category, timestamp: new Date().getTime(), author: user //設定關聯 }); article.save(); //儲存資料的到Store // 清空頁面的input輸入框 this.set('title', ""); this.set('body', ""); this.set('category', ""); this.set('username', ""); } } });
介面如下圖:
輸入上如所示資訊,點選“儲存”可以在firebase的後臺看到如下的資料關聯關係。
注意點:與這兩個資料的關聯是通過資料的id維護的。
那麼如果我要通過article獲取user的資訊要怎麼獲取呢?
直接以面向物件的方式獲取既可以。
{{#each model as |item|}}
<li>
<!--設定路由,路由的層級與router.js裡定義的要一致 -->
{{#link-to 'articles.article' item.id}}
{{item.title}} -- <small>{{item.category}}</small> -- <small>{{item.author.username}}</small>
{{/link-to}}
</li>
{{/each}}
注意看助手{{ item.author.username }}。很像EL表示式吧!!
前面提到過有兩個方式設定兩個model的關聯關係。下面的程式碼是第二種方式:
// 其他程式碼省略…… // 建立article var article = this.store.createRecord('article', { title: title, body: body, category: category, timestamp: new Date().getTime() // , // author: user //設定關聯 }); // 第二種設定關聯關係方法,在外部手動呼叫set方法設定 article.set('author', user); // 其他程式碼省略……
執行,重新錄入資訊,得到的結果是一致的。甚至你可以直接在createRecord方法裡呼叫方法來設定兩個model的關係。比如下面的程式碼段:
var store = this.store; // 由於作用域問題,在createRecord方法內部不能使用this.store var article = this.store.createRecord('article', { title: title, // …… // , // author: store.findRecord('user', 1) //設定關聯 }); // 第二種設定關聯關係方法,在外部手動呼叫set方法設定 article.set('author', store.findRecord('user', 1));
這種方式可以直接動態根據user的id屬性值獲取到記錄,再設定關聯關係。
新增介紹完了,接著介紹記錄的更新。
2,更新記錄
更新相對於新增來說非常相似。請看下面的程式碼段:
首先在模板上增加更新的設定程式碼,修改子模板articles/article.hbs:
<!-- app/templates/articles/article.hbs -->
<h1>{{model.title}}</h1>
<div>
{{model.body}}
</div>
<div>
<br><hr>
更新測試<br>
title: {{input value=model.title}}<br>
body:<br> {{textarea value=model.body cols="80" rows="3"}}<br>
<button {{action 'updateArticleById' model.id}}>更新文章資訊</button>
</div>
增加一個controller,使用者處理子模板提交的修改資訊。
ember g controller articles/article
// app/controllers/articles/article.js import Ember from 'ember'; export default Ember.Controller.extend({ actions: { // 根據文章id更新 updateArticleById: function(params) { var title = this.get('model.title'); var body = this.get('model.body'); this.store.findRecord('article', params).then(function(art) { art.set('title', title); art.set('body', body); // 儲存更新的值到Store art.save(); }); } } });
在左側選擇需要更新的資料,然後在右側輸入框中修改需要更新的資料,在修改過程中可以看到被修改的資訊會立即反應到介面上,這個是因為Ember自動更新Store中的資料(還記得很久前講過的觀察者(observer)嗎?)。
如果你沒有點選“更新文章資訊”提交,你修改的資訊不會更新到firebase。頁面重新整理後還是原來樣子,如果你點選了“更新文章資訊”資料將會把更新的資訊提交到firebase。
由於save、findRecord方法返回值是一個promises物件,所以你還可以針對出錯情況進行處理。比如下面的程式碼:
var user = this.store.createRecord('user', { // …… }); user.save().then(function(fulfill) { // 儲存成功 }).catch(function(error) { // 儲存失敗 }); this.store.findRecord('article', params).then(function(art) { // …… }).catch(function(error) { // 出錯處理程式碼 });
具體程式碼我就不演示了,請讀者自己編寫測試吧!!
3,刪除記錄
既然有了新增那麼通常就會有刪除。記錄的刪除與修改非常類似,也是首先查詢出要刪除的資料,然後執行刪除。
// app/controllers/articles.js import Ember from 'ember'; export default Ember.Controller.extend({ actions: { // 表單提交,儲存資料到Store。Store會自動更新到firebase saveItem: function() { // 省略 }, // 根據id屬性值刪除資料 delById : function(params) { // 任意獲取一個作為判斷表單輸入值 if (params && confirm("你確定要刪除這條資料嗎??")) { // 執行刪除 this.store.findRecord('article', params).then(function(art) { art.destroyRecord(); alert('刪除成功!'); }, function(error) { alert('刪除失敗!'); }); } else { return; } } } });
修改顯示資料的模板,增加刪除按鈕,並傳遞資料的id值到controller。
<!-- app/templates/articles.hbs -->
<div>
<div>
<div class="col-md-4 col-xs-4">
<ul>
{{#each model as |item|}}
<li>
<!--設定路由,路由的層級與router.js裡定義的要一致 -->
{{#link-to 'articles.article' item.id}}
{{item.title}} -- <small>{{item.category}}</small> -- <small>{{item.author.username}}</small>
{{/link-to}}
<button {{action 'delById' item.id}}>刪除</button>
</li>
{{/each}}
</ul>
// ……省略其他程式碼
</div>
</div>
結果如上圖,點選第二條資料刪除按鈕。彈出提示視窗,點選“確定”之後成功刪除資料,並彈出“刪除成功!”,到firebase後臺檢視資料,確實已經刪除成功。
然而與此關聯的user卻沒有刪除,正常情況下也應該是不刪除關聯的user資料的。
最終結果只剩下一條資料:
到此,有關新增、更新、刪除的方法介紹完畢。已經給出了詳細的演示例項,我相信,如果你也親自在自己的專案中實踐過,那麼掌握這幾個方法是很容易的!