Ember 新建、更新、刪除記錄

2018-01-06 18:00 更新

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

1,新建記錄

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





<div class="container">
    <div class="row">
        <div class="col-md-4 col-xs-4">
            <ul class="list-group">
            {{#each model as |item|}}
                <li class="list-group-item">

                    
                    {{#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>

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

//   app/controllers/articles.js


import Ember from 'ember';


export default Ember.Controller.extend({


    actions: {


        //  表單提交,保存數(shù)據(jù)到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 ;
            }


            //  創(chuàng)建數(shù)據(jù)記錄
            var article = this.store.createRecord('article', {
                title: title,
                body: body,
                category: category,
                timestamp: new Date().getTime()
            });
            article.save();  //保存數(shù)據(jù)的到Store
            //  清空頁面的input輸入框
            this.set('title', "");
            this.set('body', "");
            this.set('category', "");
        }
    }
});

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

結(jié)果截圖

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

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

ember g model users

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

//   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')  //關(guān)聯(lián)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')  //關(guān)聯(lián)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中設(shè)置這兩個模型的關(guān)聯(lián)關(guān)系。一共有兩種方式設(shè)置,一種是直接在createRecord()方法中設(shè)置,另一種是在方法外設(shè)置。

//   app/controllers/articles.js


import Ember from 'ember';


export default Ember.Controller.extend({


    actions: {


        //  表單提交,保存數(shù)據(jù)到Store。Store會自動更新到firebase
        saveItem: function() {
            //  獲取信息和校驗代碼省略……


            // 創(chuàng)建user
            var user = this.store.createRecord('user', {
                username: username,
                timestamp: new Date().getTime()
            });
            //  必須要執(zhí)行這句代碼,否則user數(shù)據(jù)不能保存到Store,
            //  否則article通過user的id查找不到user
            user.save();


            //  創(chuàng)建article
            var article = this.store.createRecord('article', {
                title: title,
                body: body,
                category: category,
                timestamp: new Date().getTime(),
                author: user   //設(shè)置關(guān)聯(lián)
            });


            article.save();  //保存數(shù)據(jù)的到Store
            //  清空頁面的input輸入框
            this.set('title', "");
            this.set('body', "");
            this.set('category', "");
            this.set('username', "");
        }
    }
});

界面截圖

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

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

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

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

{{#each model as |item|}}
    <li class="list-group-item">

        
        {{#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表達式吧??! 前面提到過有兩個方式設(shè)置兩個模型的關(guān)聯(lián)關(guān)系。下面的代碼是第二種方式:

//  其他代碼省略……
//  創(chuàng)建article
var article = this.store.createRecord('article', {
    title: title,
    body: body,
    category: category,
    timestamp: new Date().getTime()
    // ,
    // author: user   //設(shè)置關(guān)聯(lián)
});


// 第二種設(shè)置關(guān)聯(lián)關(guān)系方法,在外部手動調(diào)用set方法設(shè)置
article.set('author', user);
//  其他代碼省略……

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

var store = this.store;  // 由于作用域問題,在createRecord方法內(nèi)部不能使用this.store
var article = this.store.createRecord('article', {
    title: title,
    // ……
    // ,
    // author: store.findRecord('user', 1)   //設(shè)置關(guān)聯(lián)
});


// 第二種設(shè)置關(guān)聯(lián)關(guān)系方法,在外部手動調(diào)用set方法設(shè)置
article.set('author', store.findRecord('user', 1));

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

2,更新記錄

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





<h2>{{model.title}}</h2>
<div class = "body">
{{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: {
        // 根據(jù)文章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();
            });
        }
    }
});

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

結(jié)果截圖

如果你沒有點擊“更新文章信息”提交,你修改的信息不會更新到firebase。頁面刷新后還是原來樣子,如果你點擊了“更新文章信息”數(shù)據(jù)將會把更新的信息提交到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,刪除記錄

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

//   app/controllers/articles.js


import Ember from 'ember';


export default Ember.Controller.extend({


    actions: {


        //  表單提交,保存數(shù)據(jù)到Store。Store會自動更新到firebase
        saveItem: function() {
            // 省略
        },
        //  根據(jù)id屬性值刪除數(shù)據(jù)
        delById : function(params) {


            //  任意獲取一個作為判斷表單輸入值
            if (params && confirm("你確定要刪除這條數(shù)據(jù)嗎??")) {
                //  執(zhí)行刪除
                this.store.findRecord('article', params).then(function(art) {
                    art.destroyRecord();
                    alert('刪除成功!');
                }, function(error) {
                    alert('刪除失敗!');
                });
            } else {
                return;
            }


        }
    }
});

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





<div class="container">
    <div class="row">
        <div class="col-md-4 col-xs-4">
            <ul class="list-group">
            {{#each model as |item|}}
                <li class="list-group-item">

                    
                    {{#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>

截圖

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

截圖

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

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號