模型,保存數據到數據庫

文章來源:模型,保存數據到數據庫javascript

  1. 環境搭建以及使用Ember.js建立第一個靜態頁面
  2. 引入計算屬性、action、動態內容

繼續爲讀者介紹如何使用Ember構建一個完整的、複雜的項目。html

第一個Ember.js模型

在前面兩篇中實現瞭如何獲取界面輸入的郵箱值,可是並無真正保存到數據,僅僅只是獲取界面輸入的值並顯示出來。在本篇中將爲讀者演示如何保存數據到數據庫中。可是我並不會去建立一個數據庫,而是使用firebase,更多有關firebase的信息請自行查閱資料學習(若是訪問firebase官網很慢或者是沒法訪問那麼你須要fanqiang)!java

言歸正傳,回到Ember的模型介紹中來。簡單講Ember的模型其實就是一個與數據表對應的一個實體類,與Java中的JavaBean有點相似。
建立一個模型也很是簡單,能夠直接使用Ember CLI命令建立,下面的命令就是用於建立模型類,並在模型中增長一個string類型的屬性emailgit

ember g model invitation email:string

命令執行完畢以後能夠在項目對應目錄下看到建立的文件app/models/invitaction.js,文件內如以下:github

// app/models/invitation.js

import DS from 'ember-data';

export default DS.Model.extend({
  email: DS.attr('string')
});

有了模型類以後修改控制器index.js的代碼,加入模型,經過模型來保存數據對象。web

// app/controller/index.js

import Ember from 'ember';

export default Ember.Controller.extend({

    headerMessage: 'Coming Soon',

    responseMessage: '',  // 設置默認值爲空字符串

    emailAddress: '',  // 設置默認值爲空字符串
    //  使用正則表達式判斷郵箱格式,若是正確則返回true反之返回false
    isValid: Ember.computed.match('emailAddress', /^.+@.+\..+$/),
    // 把計算屬性isValid綁定到isDisabled上
    isDisabled: Ember.computed.not('isValid'),  //當`disabled=false`時按鈕可用,因此正好須要取反

    actions: {
        saveInvitation: function() {
            const email = this.get('emailAddress');
            //  建立一個模型對象
            const newInvitaction = this.store.createRecord('invitation', { email: email });
            newInvitaction.save();  //保存模型對象到store中
            this.set('responseMessage', `Thank you! We've just saved your email address: ${this.get('emailAddress')}`);
            //  狀況輸入框內容
            this.set('emailAddress', '');
        }
    }
});

等待項目從新啓動,在界面輸入正確的郵箱,點擊按鈕,能夠在瀏覽器控制檯看到以下錯誤信息:正則表達式

錯誤信息

爲什麼會出現這些錯誤呢??其實很簡單,咱們並無對應的後臺服務區處理數據,目前僅僅是提交了數據而已,那麼怎麼處理呢?咱們引入一個很是好用的數據庫——firebase。firebase爲Ember提交了很是豐富的API,咱們不須要再本身寫後臺的處理程序,能夠直接調用firebase提供的API便可完成數據的CRUD操做。更多有關firebase的使用教程請看EmberFire Guide,在這個參考文檔上詳細介紹了firebase如何與Ember整合,Ember如何調用firebase提供的API。sql

下面簡單介紹如何把firebase整合到本項目中。數據庫

  1. 安裝 ember install emberfire,會自動建立文件app/adapters/application.js
  2. 在firebase官網註冊一個用戶,並建立一個APP(以下圖1位置建立APP)而後會獲得一個管理鏈接(好比:luminous-xxx-xxx.firebaseIO.com)
  3. 修改項目中config/environment.js,在文件中增長firebase的配置。

圖1
圖1ubuntu

config/environment.js配置代碼以下:

var ENV = {
    modulePrefix: 'library-app',
    environment: environment,
    contentSecurityPolicy: { 'connect-src': "'self' https://auth.firebase.com wss://*.firebaseio.com" },
    firebase: 'https://YOUR-FIREBASE-NAME.firebaseio.com/',  //改爲本身在firebase上APP的地址
    baseURL: '/',
    locationType: 'auto',
    EmberENV: {
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. 'with-controller': true
      }
    },

    APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
    }
  };
//  ……其餘代碼省略

注意上述代碼中的第5行,firebase屬性的值是本身在firebase申請的APP的URL。必定記得要修改!!!

修改完成以後手動重啓項目,記得是手動關閉終端運行的項目(ctrl+c關閉),而後再使用命令ember s啓動項目。不然新安裝的emberfire沒法起做用。

等待項目啓動完成,若是啓動過程當中沒有出現錯誤,說明emberfire安裝成功!

而後激動的時刻到了,在首頁輸入正確的郵箱,點擊按鈕,能夠看到瀏覽器控制來不會報錯了!而且在firebase官網的APP中看到剛剛新增的郵箱!!

注意:點擊按鈕提交後可能看到界面沒有任何反應,先別急,因爲firebase是外國的東西,在天朝訪問都是比較慢,你懂的。提交後到響應回來可能比較慢。

從瀏覽器控制檯打印的日誌能夠看出向firebase發送請求,截圖以下:

向firebase發送請求截圖

而且在界面上提示了保存成功的信息!

最後在firebase官網上能夠查看到剛剛提交數據。

提交到firebase的數據

能夠感覺到firebase的強大了吧!咱們幾乎沒有作任何處理數據就直接保存到firebase了,而且會自動根據模型建立數據,不過須要注意的是咱們在模型定義中並不須要定義id屬性,firebase會自動生成一個惟一的id屬性值,截圖中的-KEr3XwUQjgLjb5yx0dp就是id屬性值。

到此,數據的保存工做完成了,藉助firebase大大簡化了本身須要處理的東西,不須要本身建立數據庫、數據表、以及保存數據sql等等!不知道你是否看明白了,若是有疑問請及時給我留言,我會盡力爲你解答!

promise和this

promise(承諾)在JavaScript中是一個異步特性。這個特性還在完善之中,更多有關promise的介紹請看promises-book或者Mozilla MDN Promise

在前面保存數據的代碼中save()方法返回值就是一個promise,咱們能夠根據save()方法的返回值作不一樣的處理,好比保存失敗時候的處理。

saveInvitation: function() {
            const email = this.get('emailAddress');
            //  建立一個模型對象
            const newInvitaction = this.store.createRecord('invitation', { email: email });
             //保存模型對象到store中
            newInvitaction.save().then(function(msg) {
                console.log('保存成功。');
            }, function(reason) {
                console.log('保存失敗!');
            });
            this.set('responseMessage', `Thank you! We've just saved your email address: ${this.get('emailAddress')}`);
            //  狀況輸入框內容
            this.set('emailAddress', '');
        }

若是你看過有關promise的介紹那麼理解上述代碼應該是很簡單的,在方法then()中第一個函數(參數)會在save()執行成功的時候執行,第二個函數(參數)會在save()執行失敗的時候執行。明白這個以後咱們再修改控制器index.js的代碼。咱們把提示信息放在save()執行成功的時候執行方法中。

saveInvitation: function() {
            const email = this.get('emailAddress');
            //  建立一個模型對象
            const newInvitaction = this.store.createRecord('invitation', { email: email });
             //保存模型對象到store中
            newInvitaction.save().then(function(msg) {
                this.set('responseMessage', `Thank you! We've just saved your email address: ${this.get('emailAddress')}`);
                //  狀況輸入框內容
                this.set('emailAddress', '');
            }, function(reason) {
                this.set('responseMessage', `Saved: ${this.get('emailAddress')} failed!`);
                //  狀況輸入框內容
                this.set('emailAddress', '');
            });
        }

等待項目自動重啓完成,在界面輸入正確郵箱,提交數據,此時並無出現任何反應,而且會在瀏覽器控制檯看到以下錯誤,

錯誤信息

這又是什麼緣由呢?其實緣由很簡單,由於this做用域問題,因爲是在then()內部使用了this致使此時的this指向的並非控制器類了,只有在Ember的上下文中才能使用set()方法!咱們用一個臨時變量解決這個問題,代碼修改成以下:

// app/controller/index.js

import Ember from 'ember';

export default Ember.Controller.extend({

    headerMessage: 'Coming Soon',

    responseMessage: '',  // 設置默認值爲空字符串

    emailAddress: '',  // 設置默認值爲空字符串
    //  使用正則表達式判斷郵箱格式,若是正確則返回true反之返回false
    isValid: Ember.computed.match('emailAddress', /^.+@.+\..+$/),
    // 把計算屬性isValid綁定到isDisabled上
    isDisabled: Ember.computed.not('isValid'),  //當`disabled=false`時按鈕可用,因此正好須要取反

    actions: {
        saveInvitation: function() {
            const email = this.get('emailAddress');
            //  建立一個模型對象
            const newInvitaction = this.store.createRecord('invitation', { email: email });
            var _this = this;
             //保存模型對象到store中
            newInvitaction.save().then(function(msg) {
                _this.set('responseMessage', `Thank you! We've just saved your email address: ${_this.get('emailAddress')}`);
                //  狀況輸入框內容
                _this.set('emailAddress', '');
            }, function(reason) {
                _this.set('responseMessage', `Saved: ${_this.get('emailAddress')} failed!`);
                //  狀況輸入框內容
                _this.set('emailAddress', '');
            });
        }
    }

});

等待項目自動重啓完成,在頁面輸入正確的郵箱並提交,能夠看到此時效果與以前是同樣的,而後去firebase查看結果,也是能夠看到新增的數據。

雖然是用臨時變量方式能夠解決因爲this做用域問題,可是還有更加優美的解決辦法,現在幾乎全部新版的瀏覽器引擎已經支持ES2015,可使用ES2015的=>操做符解決this做用域問題,請看下面的處理代碼:

saveInvitation: function() {
    const email = this.get('emailAddress');
    //  建立一個模型對象
    const newInvitaction = this.store.createRecord('invitation', { email: email });
    
     //保存模型對象到store中
    newInvitaction.save().then((response) => {
        console.log('response = ' + response);
        this.set('responseMessage', `Thank you! We've just saved your email address: ${response.get('id')}`);
        //  狀況輸入框內容
        this.set('emailAddress', '');
    }, (reason) => {
        this.set('responseMessage', `Saved: ${this.get('emailAddress')} failed!`);
        //  狀況輸入框內容
        this.set('emailAddress', '');
    });
}

使用ES2015的特性以後不只解決了this做用域問題,並且連關鍵字function都不須要了,使用=>操做會自動把外層this所指的對象傳遞到函數內部,而且修改了保存成功時的提示信息,使用${response.get('id')}從firebase響應的數據中獲取到保存成功後返回的id值,返回的response就是一個模型invitation的對象,可使用get()方法獲取對象值。
再次測試,若是項目代碼沒有誤那麼你能夠獲得以下截圖的提示信息(id值跟你的是不同的),

使用ES2015後保存截圖

若是你對this不是很懂,請看認真看下面文章的解釋:

  1. Mozilla MDN this
  2. Javascript的this用法

建立管理頁面

前面已經介紹瞭如何整合firebase到項目中,而且已經成功保存增長的數據。能夠在firebase上看到全部數據,咱們建立一個後臺頁面去管理這些數據。

下面建立一個子路由和路由對應的模板頁面,仍然是使用Ember CLI命令建立,命令以下:

ember g route admin/invitaction

命令執行完畢後會獲得一個路由文件(app/routes/admin/invitaction.js)和一個模板文件(app/templates/admin/invitaction.hbs),命令會自動建立文件夾admin,子路由和子模板會放在子子目錄下。
而後在首頁增長菜單連接,修改navbar.hbs模板。

<!-- app/templates/navbar.hbs -->
<nav class="navbar navbar-inverse">
  <div class="container-fluid">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-navbar">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      {{#link-to 'index' class="navbar-brand"}}Library App{{/link-to}}
    </div>

    <div class="collapse navbar-collapse" id="main-navbar">
      <ul class="nav navbar-nav">
            {{#link-to 'index' tagName="li"}}<a href>Home</a>{{/link-to}}
            {{#link-to 'about' tagName="li"}}<a href>About</a>{{/link-to}}
            {{#link-to 'contact' tagName="li"}}<a href>Contact</a>{{/link-to}}
      </ul>
      <!-- 後臺管理頁面連接 -->
      <ul class="nav navbar-nav navbar-right">
          <li class="dropdown">
              <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Admin<span class="caret"></span></a>
              <ul class="dropdown-menu">
                  {{#link-to 'admin.invitation' tagName="li"}}<a href="">Invitations</a>{{/link-to}}
              </ul>
          </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

代碼{{#link-to 'admin.invitation' tagName="li"}}<a href="">Invitations</a>{{/link-to}}admin.invitation是一個嵌套路由或者說是子路由。更多有關路由嵌套問題請看Ember.js 入門指南之十三{{link-to}} 助手

在模板中使用表格遍歷顯示全部的郵箱數據。修改模板invitaction.hbs

<!-- app/templates/admin/invitations.hbs -->

<h1>Invitations</h1>

<table class="table table-bordered table-striped">
    <thead>
      <tr>
          <th>ID</th>
          <th>E-mail</th>
      </tr>
    </thead>
    <tbody>
    {{#each model as |invitation|}}
        <tr>
            <th>{{invitation.id}}</th>
            <td>{{invitation.email}}</td>
        </tr>
    {{/each}}

    </tbody>
</table>

上述代碼中{{#each}}{{/each}}是Ember提供的遍歷表達式,此表達式用於遍歷數組數據。本例子中用戶遍歷從路由的model回調中返回的數據。更多有關此表達式的介紹請看Ember.js 入門指南之十handlebars遍歷標籤
修改路由app/routes/admin/invitations.jsmodel回調中獲取服務器(firebase)上的數據。

// app/routes/admin/invitations.js
import Ember from 'ember';

export default Ember.Route.extend({

  model() {
    return this.store.findAll('invitation');
  }

});

等待項目重啓完成,能夠在項目首頁導航欄的右側看到能夠點擊下拉的Admin菜單項,點擊菜單看到子菜單項「Invitation」,點擊「Invitation」進入到http://localhost:4200/admin/invitation
在界面上能夠看到以前新增的全部郵箱信息和firebase自動生成的ID屬性值(因爲firebase是老外的東西獲取數據會比較慢,數據顯示天然也會比較慢,稍等一會就在界面上看到了!)。若是你項目代碼沒問題也能夠看到以下的截圖。

Invitation數據截圖

數據的CRUD操做

到這一步咱們已經能夠完整的從服務器獲取數據,並以列表形式顯示在界面上。本教程的目標是建立一個簡單的圖書管理系統,前面的文章已經完成了相似於用戶註冊的功能,接下來咱們建立一個library模型,用於保存書庫信息。
一樣是使用Ember CLI命令建立模型。

ember g model library name:string address:string phone:string

上述命令建立了一個包含三個屬性的模型,這三個屬性都是string類型的數據。建立完模型以後再繼續建立三個模板,分別用戶顯示library列表新建library數據。

ember g template libraries
ember g template libraries/index
ember g template libraries/new

模板建立完畢以後手動在router.js中增長路由配置,此次咱們不採用Ember CLI命令建立了!!!

// app/router.js

import Ember from 'ember';
import config from './config/environment';

var Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function() {

  this.route('about');
  this.route('contact');

  this.route('admin', function() {
    this.route('invitation');
  });

  this.route('libraries', function() {
    this.route('new');
  });
});

export default Router;

再更新首頁模板navbar.hbs,增長一個菜單項「libraries」,其餘代碼不變。

<ul class="nav navbar-nav">
    {{#link-to 'index' tagName="li"}}<a href="">Home</a>{{/link-to}}
    {{#link-to 'libraries' tagName="li"}}<a href="">Libraries</a>{{/link-to}}
    {{#link-to 'about' tagName="li"}}<a href="">About</a>{{/link-to}}
    {{#link-to 'contact' tagName="li"}}<a href="">Contact</a>{{/link-to}}
</ul>

修改模板libraries.hbs,增長菜單連接。

<!-- app/templates/libraries.hbs -->
<h1>Libraries</h1>

<div class="well">
    <ul class="nav nav-pills">
      {{#link-to 'libraries.index' tagName="li"}}<a href="">List all</a>{{/link-to}}
      {{#link-to 'libraries.new' tagName="li"}}<a href="">Add new</a>{{/link-to}}
    </ul>
</div>
<!-- 子模板new.hbs、index.hbs會渲染到outlet上 -->
{{outlet}}

等待項目重啓完成,進入http://localhost:4200/libraries。能夠看到以下圖的界面

libraries界面

此時點擊界面的上的「List all」和「Add new」除了看到URL變化以外還沒任何效果,由於咱們的子模板libraries/index.hbslibraries/new.hbs尚未任何內容,下面在這兩個模板中增長一些代碼。

<!-- app/templates/libraries/index.hbs -->
<h2>List</h2>

{{#each model as |library|}}
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">{{library.name}}</h3>
        </div>
        <div class="panel-body">
            <p>Address: {{library.address}}</p>
            <p>Phone: {{library.phone}}</p>
        </div>
    </div>
{{/each}}
<!-- app/templates/libraries/new.hbs -->
<h2>Add a new local Library</h2>

<div class="form-horizontal">
    <div class="form-group">
        <label class="col-sm-2 control-label">Name</label>
        <div class="col-sm-10">
            {{input type="text" value=model.name class="form-control" placeholder="The name of the Library"}}
        </div>
    </div>
    <div class="form-group">
        <label class="col-sm-2 control-label">Address</label>
        <div class="col-sm-10">
            {{input type="text" value=model.address class="form-control" placeholder="The address of the Library"}}
        </div>
    </div>
    <div class="form-group">
        <label class="col-sm-2 control-label">Phone</label>
        <div class="col-sm-10">
            {{input type="text" value=model.phone class="form-control" placeholder="The phone number of the Library"}}
        </div>
    </div>
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-default" {{action 'saveLibrary' model}}>Add to library list</button>
        </div>
    </div>
</div>

模板new.hbs是一個表單,用於新增數據,經過點擊按鈕「Add to library list」提交表單數據,表單數據由路由libraries/new.js中的saveLibrary方法處理,此時此方法還沒定義,在接下來的代碼中會定義。
{{action}}表達式中傳遞了一個參數model處處理的後臺,表單中的其餘屬性會以model的屬性方式傳遞到後臺,之因此能夠這樣作是由於在模板對應的路由中返回了一個空的library對象,在接下來的路由libraries/new.js將看到。
等待項目重啓完,在點擊「List all」和「Add new」能夠看到這兩個子模板的內容渲染到父模板libraries.hbs{{outlet}}上。不過因爲並無在路由中獲取模型library的數據因此「List all」頁面尚未任何數據,「Add new」頁面是第一個新增數據吧表單。
下面在路由libraries/index.js中獲取library的數據,並在model回調中返回到模板中遍歷顯示。
使用Ember CLI命令建立路由,建立過程會詢問是否覆蓋已經存在的模板文件,輸入n選擇否。

ember g route libraries/index
ember g route libraries/new

路由建立完成以後分別在這兩個路由中增長獲取數據的代碼。

// app/routes/libraries/index.js
import Ember from 'ember';

export default Ember.Route.extend({

  model() {
    return this.store.findAll('library');
  }

});
// app/routes/libraries/new.js
import Ember from 'ember';

export default Ember.Route.extend({

  model() {
    return this.store.createRecord('library');
  },

  actions: {
    //  處理模板上輸入的數據
    saveLibrary(newLibrary) {
      newLibrary.save().then(() => this.transitionTo('libraries'));
    },

    willTransition() {
      // rollbackAttributes() removes the record from the store
      // if the model 'isNew'
      this.controller.get('model').rollbackAttributes();
    }
  }
});

在此路由的model回調中咱們建立了一個空的library對象,並返回到模板頁面。這也是爲何能在模板中傳遞參數model的緣由。
代碼中方法willTransition()是Ember提供的內置方法,此方法的做用是當用戶離開當前URL時會清空未保存到服務器的library數據,若是不重置modelEmber會在路由切換的時候自動保存數據到服務器上。
保存數據的方法saveLibrary()寫的比較簡潔,它的做用是:先調用save()方法保存數據,若是保存成功在調用方法transitionTo()跳轉到路由libraries下(library首頁),有關=>語法的介紹請看Mozill MDN Arrow_functions
在上述代碼中屢次是用了this.controller,可是在路由中並無這個屬性controller並且也沒有控制器文件app/controllers/libraries/new.js,運行項目並不會報錯!這是爲何呢?這是由於Ember會自動生成一個虛擬的控制器並在保存在內存中,根據Ember的命名規則會自動生成一個與路由同名的控制器,
爲了驗證這個說法,打開瀏覽器的控制檯,在打開標籤「Ember」而後點擊左側的「/# Routes」,找到路由libraries這一塊,能夠看到以下截圖的信息。

自動生成控制器

能夠看到每一個路由都對應着一個同名的控制器。

等待項目重啓完畢,開始驗證代碼是否實現了所設想的要求。
首先在新增頁面輸入以下截圖信息,而後點擊按鈕保存數據。

新增library數據

稍等片刻,等待數據保存完畢,能夠看到界面順利跳轉到了http://localhost:4200/libraries下,以下圖所示,而且看到了剛剛新增的數據,爲了驗證數據是否真的保存到服務器中,咱們進入到firebase的APP中查看,能夠看到數據以及保存到裏library下。

libraries頁面

library數據列表頁面截圖

firebase頁面

firebase上保存的library數據截圖

此時,若是你註釋了方法willTransition()結果會是怎麼樣的呢!!若是沒有這個方法去重置model,當你每次在「Add new」頁面輸入輸入而且沒有點擊「Add to library list」保存數,而後切換到其餘路由下(好比點擊「List all」切換到路由libraries下)會自動保存一條數據到服務器。

  • 在「Add new」頁面輸入以下截圖數據

未提交保存的數據

  • 點擊按鈕「List all」切換到路由libraries下,能夠看到在「Add new」頁面添加的數據,以下圖所示,可是若是你手動刷新頁面後能夠發現這條數據不見了,而且在firebase上也沒有這條數據,可見這條數據僅僅是保存到Ember的store中,並無真正保存到服務器上。這樣的體驗是很是糟糕的!!

顯示爲提交保存的數據

其中,實現重置model的方式還有另一種更加合適的方法,代碼以下:

willTransition() {
  // rollbackAttributes() removes the record from the store
  // if the model 'isNew'
//   this.controller.get('model').rollbackAttributes();

  let model = this.controller.get('model');

  if (model.get('isNew')) {
    model.destroyRecord();
  }
}

本篇的內容到此所有介紹完畢!本篇咱們實現了數據的保存、顯示,特別是library數據的保存。數據的保存、顯示都須要與模型關聯,模型在Ember是一個很是重要的內容!但願讀者好好掌握模型。

家庭做業

下面兩個做業完成其中之一便可。本篇選擇第一個,第二個請讀者自行完成!動手纔是真理。

加強contact的功能

  1. 建立一個包括兩個屬性emailmessage的模型contact參考代碼
  2. 修改路由app/routes/contact.js返回一個空對象到模板上,參考代碼
  3. 修改控制器contact.js,保存數據到firebase,參考代碼
  4. 把放在控制器中的校驗代碼移動到模型app/models/contact.js中,參考代碼
  5. 建立一個管理contact的後臺頁面http://localhost:4200/admin/contacts參考代碼
  6. 在項目首頁的導航菜單上增長一個菜單項「Contacts」,點擊菜單進入http://localhost:4200/admin/contact參考代碼
  7. 使用表格展現全部的contact數據,參考代碼

使用路由和模型重構有關contact的代碼

  1. 把有關contact的檢驗放到模型類中
  2. 把控制器contact.js中保存數據的代碼移動到同名的路由中
  3. 測試經過後刪除控制器contact.js

做業演示結果

新增contact信息

當輸入的郵箱格式正確,而且message長度大於6時按鈕「send」纔可用。

新增contact信息成功

保存成功後狀況輸入框,而且顯示提示信息。當切換路由後再進入到http://localhost:4200/contact會清空保存成功的提示信息。

後臺Contact列表

後臺頁面成功顯示了新增的數據,即便手動刷新頁面數據也不會丟失,可見數據已經保存到firebase,在此再也不貼firebase上的數據截圖了!



爲了照顧懶人我把完整的代碼放在GitHub上,若有須要請參考參考。博文通過屢次修改,博文上的代碼與github代碼可能有出入,不過影響不大!若是你以爲博文對你有點用,請在github項目上給我點個star吧。您的確定對我來講是最大的動力!!

相關文章
相關標籤/搜索