1. 程式人生 > >Ember.js 入門指南——新建、更新、刪除記錄

Ember.js 入門指南——新建、更新、刪除記錄

前一篇介紹了查詢方法,本篇介紹新建、更新、刪除記錄的方法。

本篇的示例程式碼建立在上一篇的基礎上。對於整合firebase、建立routetemplate請參看上一篇,增加一個controllerember 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));

       這種方式可以直接動態根據userid屬性值獲取到記錄,再設定關聯關係。

       新增介紹完了,接著介紹記錄的更新。

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

       由於savefindRecord方法返回值是一個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資料的。

最終結果只剩下一條資料:

到此,有關新增、更新、刪除的方法介紹完畢。已經給出了詳細的演示例項,我相信,如果你也親自在自己的專案中實踐過,那麼掌握這幾個方法是很容易的!