成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

模型,保存數(shù)據(jù)到數(shù)據(jù)庫

paulli3 / 3593人閱讀

摘要:文章來源模型,保存數(shù)據(jù)到數(shù)據(jù)庫環(huán)境搭建以及使用創(chuàng)建第一個靜態(tài)頁面引入計算屬性動態(tài)內(nèi)容繼續(xù)為讀者介紹如何使用構(gòu)建一個完整的復(fù)雜的項目。

文章來源:模型,保存數(shù)據(jù)到數(shù)據(jù)庫

環(huán)境搭建以及使用Ember.js創(chuàng)建第一個靜態(tài)頁面

引入計算屬性、action、動態(tài)內(nèi)容

繼續(xù)為讀者介紹如何使用Ember構(gòu)建一個完整的、復(fù)雜的項目。

第一個Ember.js模型

在前面兩篇中實現(xiàn)了如何獲取界面輸入的郵箱值,但是并沒有真正保存到數(shù)據(jù),僅僅只是獲取界面輸入的值并顯示出來。在本篇中將為讀者演示如何保存數(shù)據(jù)到數(shù)據(jù)庫中。但是我并不會去創(chuàng)建一個數(shù)據(jù)庫,而是使用firebase,更多有關(guān)firebase的信息請自行查閱資料學(xué)習(xí)(如果訪問firebase官網(wǎng)很慢或者是無法訪問那么你需要fanqiang)!

言歸正傳,回到Ember的模型介紹中來。簡單講Ember的模型其實就是一個與數(shù)據(jù)表對應(yīng)的一個實體類,與Java中的JavaBean有點類似。
創(chuàng)建一個模型也非常簡單,可以直接使用Ember CLI命令創(chuàng)建,下面的命令就是用于創(chuàng)建模型類,并在模型中增加一個string類型的屬性email。

ember g model invitation email:string

命令執(zhí)行完畢之后可以在項目對應(yīng)目錄下看到創(chuàng)建的文件app/models/invitaction.js,文件內(nèi)如如下:

// app/models/invitation.js

import DS from "ember-data";

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

有了模型類之后修改控制器index.js的代碼,加入模型,通過模型來保存數(shù)據(jù)對象。

// app/controller/index.js

import Ember from "ember";

export default Ember.Controller.extend({

    headerMessage: "Coming Soon",

    responseMessage: "",  // 設(shè)置默認(rèn)值為空字符串

    emailAddress: "",  // 設(shè)置默認(rèn)值為空字符串
    //  使用正則表達(dá)式判斷郵箱格式,如果正確則返回true反之返回false
    isValid: Ember.computed.match("emailAddress", /^.+@.+..+$/),
    // 把計算屬性isValid綁定到isDisabled上
    isDisabled: Ember.computed.not("isValid"),  //當(dāng)`disabled=false`時按鈕可用,所以正好需要取反

    actions: {
        saveInvitation: function() {
            const email = this.get("emailAddress");
            //  創(chuàng)建一個模型對象
            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")}`);
            //  情況輸入框內(nèi)容
            this.set("emailAddress", "");
        }
    }
});

等待項目重新啟動,在界面輸入正確的郵箱,點擊按鈕,可以在瀏覽器控制臺看到如下錯誤信息:

為何會出現(xiàn)這些錯誤呢??其實很簡單,我們并沒有對應(yīng)的后臺服務(wù)區(qū)處理數(shù)據(jù),目前僅僅是提交了數(shù)據(jù)而已,那么怎么處理呢?我們引入一個非常好用的數(shù)據(jù)庫——firebase。firebase為Ember提交了非常豐富的API,我們不需要再自己寫后臺的處理程序,可以直接調(diào)用firebase提供的API即可完成數(shù)據(jù)的CRUD操作。更多有關(guān)firebase的使用教程請看EmberFire Guide,在這個參考文檔上詳細(xì)介紹了firebase如何與Ember整合,Ember如何調(diào)用firebase提供的API。

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

安裝 ember install emberfire,會自動創(chuàng)建文件app/adapters/application.js

在firebase官網(wǎng)注冊一個用戶,并創(chuàng)建一個APP(如下圖1位置創(chuàng)建APP)然后會得到一個管理連接(比如:luminous-xxx-xxx.firebaseIO.com)

修改項目中config/environment.js,在文件中增加firebase的配置。


圖1

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。一定記得要修改?。?!

修改完成之后手動重啟項目,記得是手動關(guān)閉終端運行的項目(ctrl+c關(guān)閉),然后再使用命令ember s啟動項目。否則新安裝的emberfire無法起作用。

等待項目啟動完成,如果啟動過程中沒有出現(xiàn)錯誤,說明emberfire安裝成功!

然后激動的時刻到了,在首頁輸入正確的郵箱,點擊按鈕,可以看到瀏覽器控制來不會報錯了!并且在firebase官網(wǎng)的APP中看到剛剛新增的郵箱??!

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

從瀏覽器控制臺打印的日志可以看出向firebase發(fā)送請求,截圖如下:

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

最后在firebase官網(wǎng)上可以查看到剛剛提交數(shù)據(jù)。

可以感受到firebase的強(qiáng)大了吧!我們幾乎沒有做任何處理數(shù)據(jù)就直接保存到firebase了,并且會自動根據(jù)模型創(chuàng)建數(shù)據(jù),不過需要注意的是我們在模型定義中并不需要定義id屬性,firebase會自動生成一個唯一的id屬性值,截圖中的-KEr3XwUQjgLjb5yx0dp就是id屬性值。

到此,數(shù)據(jù)的保存工作完成了,借助firebase大大簡化了自己需要處理的東西,不需要自己創(chuàng)建數(shù)據(jù)庫、數(shù)據(jù)表、以及保存數(shù)據(jù)sql等等!不知道你是否看明白了,如果有疑問請及時給我留言,我會盡力為你解答!

promise和this

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

在前面保存數(shù)據(jù)的代碼中save()方法返回值就是一個promise,我們可以根據(jù)save()方法的返回值做不同的處理,比如保存失敗時候的處理。

        saveInvitation: function() {
            const email = this.get("emailAddress");
            //  創(chuàng)建一個模型對象
            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")}`);
            //  情況輸入框內(nèi)容
            this.set("emailAddress", "");
        }

如果你看過有關(guān)promise的介紹那么理解上述代碼應(yīng)該是很簡單的,在方法then()中第一個函數(shù)(參數(shù))會在save()執(zhí)行成功的時候執(zhí)行,第二個函數(shù)(參數(shù))會在save()執(zhí)行失敗的時候執(zhí)行。明白這個之后我們再修改控制器index.js的代碼。我們把提示信息放在save()執(zhí)行成功的時候執(zhí)行方法中。

        saveInvitation: function() {
            const email = this.get("emailAddress");
            //  創(chuàng)建一個模型對象
            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")}`);
                //  情況輸入框內(nèi)容
                this.set("emailAddress", "");
            }, function(reason) {
                this.set("responseMessage", `Saved: ${this.get("emailAddress")} failed!`);
                //  情況輸入框內(nèi)容
                this.set("emailAddress", "");
            });
        }

等待項目自動重啟完成,在界面輸入正確郵箱,提交數(shù)據(jù),此時并沒有出現(xiàn)任何反應(yīng),并且會在瀏覽器控制臺看到如下錯誤,

這又是什么原因呢?其實原因很簡單,因為this作用域問題,由于是在then()內(nèi)部使用了this導(dǎo)致此時的this指向的并不是控制器類了,只有在Ember的上下文中才能使用set()方法!我們用一個臨時變量解決這個問題,代碼修改為如下:

// app/controller/index.js

import Ember from "ember";

export default Ember.Controller.extend({

    headerMessage: "Coming Soon",

    responseMessage: "",  // 設(shè)置默認(rèn)值為空字符串

    emailAddress: "",  // 設(shè)置默認(rèn)值為空字符串
    //  使用正則表達(dá)式判斷郵箱格式,如果正確則返回true反之返回false
    isValid: Ember.computed.match("emailAddress", /^.+@.+..+$/),
    // 把計算屬性isValid綁定到isDisabled上
    isDisabled: Ember.computed.not("isValid"),  //當(dāng)`disabled=false`時按鈕可用,所以正好需要取反

    actions: {
        saveInvitation: function() {
            const email = this.get("emailAddress");
            //  創(chuàng)建一個模型對象
            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")}`);
                //  情況輸入框內(nèi)容
                _this.set("emailAddress", "");
            }, function(reason) {
                _this.set("responseMessage", `Saved: ${_this.get("emailAddress")} failed!`);
                //  情況輸入框內(nèi)容
                _this.set("emailAddress", "");
            });
        }
    }

});

等待項目自動重啟完成,在頁面輸入正確的郵箱并提交,可以看到此時效果與之前是一樣的,然后去firebase查看結(jié)果,也是可以看到新增的數(shù)據(jù)。

雖然是用臨時變量方式可以解決由于this作用域問題,但是還有更加優(yōu)美的解決辦法,如今幾乎所有新版的瀏覽器引擎已經(jīng)支持ES2015,可以使用ES2015的=>操作符解決this作用域問題,請看下面的處理代碼:

saveInvitation: function() {
    const email = this.get("emailAddress");
    //  創(chuàng)建一個模型對象
    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")}`);
        //  情況輸入框內(nèi)容
        this.set("emailAddress", "");
    }, (reason) => {
        this.set("responseMessage", `Saved: ${this.get("emailAddress")} failed!`);
        //  情況輸入框內(nèi)容
        this.set("emailAddress", "");
    });
}

使用ES2015的特性之后不僅解決了this作用域問題,而且連關(guān)鍵字function都不需要了,使用=>操作會自動把外層this所指的對象傳遞到函數(shù)內(nèi)部,并且修改了保存成功時的提示信息,使用${response.get("id")}從firebase響應(yīng)的數(shù)據(jù)中獲取到保存成功后返回的id值,返回的response就是一個模型invitation的對象,可以使用get()方法獲取對象值。
再次測試,如果項目代碼沒有誤那么你可以得到如下截圖的提示信息(id值跟你的是不一樣的),

如果你對this不是很懂,請看認(rèn)真看下面文章的解釋:

Mozilla MDN this

Javascript的this用法

創(chuàng)建管理頁面

前面已經(jīng)介紹了如何整合firebase到項目中,并且已經(jīng)成功保存增加的數(shù)據(jù)。可以在firebase上看到所有數(shù)據(jù),我們創(chuàng)建一個后臺頁面去管理這些數(shù)據(jù)。

下面創(chuàng)建一個子路由和路由對應(yīng)的模板頁面,仍然是使用Ember CLI命令創(chuàng)建,命令如下:

ember g route admin/invitaction

命令執(zhí)行完畢后會得到一個路由文件(app/routes/admin/invitaction.js)和一個模板文件(app/templates/admin/invitaction.hbs),命令會自動創(chuàng)建文件夾admin,子路由和子模板會放在子子目錄下。
然后在首頁增加菜單鏈接,修改navbar.hbs模板。


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

在模板中使用表格遍歷顯示所有的郵箱數(shù)據(jù)。修改模板invitaction.hbs。



Invitations

{{#each model as |invitation|}} {{/each}}
ID E-mail
{{invitation.id}} {{invitation.email}}

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

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

export default Ember.Route.extend({

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

});

等待項目重啟完成,可以在項目首頁導(dǎo)航欄的右側(cè)看到可以點擊下拉的Admin菜單項,點擊菜單看到子菜單項“Invitation”,點擊“Invitation”進(jìn)入到http://localhost:4200/admin/invitation。
在界面上可以看到之前新增的所有郵箱信息和firebase自動生成的ID屬性值(由于firebase是老外的東西獲取數(shù)據(jù)會比較慢,數(shù)據(jù)顯示自然也會比較慢,稍等一會就在界面上看到了?。H绻沩椖看a沒問題也可以看到如下的截圖。

數(shù)據(jù)的CRUD操作

到這一步我們已經(jīng)可以完整的從服務(wù)器獲取數(shù)據(jù),并以列表形式顯示在界面上。本教程的目標(biāo)是創(chuàng)建一個簡單的圖書管理系統(tǒng),前面的文章已經(jīng)完成了類似于用戶注冊的功能,接下來我們創(chuàng)建一個library模型,用于保存書庫信息。
同樣是使用Ember CLI命令創(chuàng)建模型。

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

上述命令創(chuàng)建了一個包含三個屬性的模型,這三個屬性都是string類型的數(shù)據(jù)。創(chuàng)建完模型之后再繼續(xù)創(chuàng)建三個模板,分別用戶顯示library列表新建library數(shù)據(jù)。

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

模板創(chuàng)建完畢之后手動在router.js中增加路由配置,這次我們不采用Ember CLI命令創(chuàng)建了?。?!

// 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,增加一個菜單項“l(fā)ibraries”,其他代碼不變。

修改模板libraries.hbs,增加菜單鏈接。


Libraries

{{outlet}}

等待項目重啟完成,進(jìn)入http://localhost:4200/libraries??梢钥吹饺缦聢D的界面

此時點擊界面的上的“List all”和“Add new”除了看到URL變化之外還沒任何效果,因為我們的子模板libraries/index.hbs、libraries/new.hbs還沒有任何內(nèi)容,下面在這兩個模板中增加一些代碼。


List

{{#each model as |library|}}

{{library.name}}

Address: {{library.address}}

Phone: {{library.phone}}

{{/each}}

Add a new local Library

{{input type="text" value=model.name class="form-control" placeholder="The name of the Library"}}
{{input type="text" value=model.address class="form-control" placeholder="The address of the Library"}}
{{input type="text" value=model.phone class="form-control" placeholder="The phone number of the Library"}}

模板new.hbs是一個表單,用于新增數(shù)據(jù),通過點擊按鈕“Add to library list”提交表單數(shù)據(jù),表單數(shù)據(jù)由路由libraries/new.js中的saveLibrary方法處理,此時此方法還沒定義,在接下來的代碼中會定義。
{{action}}表達(dá)式中傳遞了一個參數(shù)model到處理的后臺,表單中的其他屬性會以model的屬性方式傳遞到后臺,之所以可以這樣做是因為在模板對應(yīng)的路由中返回了一個空的library對象,在接下來的路由libraries/new.js將看到。
等待項目重啟完,在點擊“List all”和“Add new”可以看到這兩個子模板的內(nèi)容渲染到父模板libraries.hbs{{outlet}}上。不過由于并沒有在路由中獲取模型library的數(shù)據(jù)所以“List all”頁面還沒有任何數(shù)據(jù),“Add new”頁面是第一個新增數(shù)據(jù)吧表單。
下面在路由libraries/index.js中獲取library的數(shù)據(jù),并在model回調(diào)中返回到模板中遍歷顯示。
使用Ember CLI命令創(chuàng)建路由,創(chuàng)建過程會詢問是否覆蓋已經(jīng)存在的模板文件,輸入n選擇否。

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

路由創(chuàng)建完成之后分別在這兩個路由中增加獲取數(shù)據(jù)的代碼。

// 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: {
    //  處理模板上輸入的數(shù)據(jù)
    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回調(diào)中我們創(chuàng)建了一個空的library對象,并返回到模板頁面。這也是為什么能在模板中傳遞參數(shù)model的原因。
代碼中方法willTransition()是Ember提供的內(nèi)置方法,此方法的作用是當(dāng)用戶離開當(dāng)前URL時會清空未保存到服務(wù)器的library數(shù)據(jù),如果不重置modelEmber會在路由切換的時候自動保存數(shù)據(jù)到服務(wù)器上。
保存數(shù)據(jù)的方法saveLibrary()寫的比較簡潔,它的作用是:先調(diào)用save()方法保存數(shù)據(jù),如果保存成功在調(diào)用方法transitionTo()跳轉(zhuǎn)到路由libraries下(library首頁),有關(guān)=>語法的介紹請看Mozill MDN Arrow_functions。
在上述代碼中多次是用了this.controller,但是在路由中并沒有這個屬性controller而且也沒有控制器文件app/controllers/libraries/new.js,運行項目并不會報錯!這是為什么呢?這是因為Ember會自動生成一個虛擬的控制器并在保存在內(nèi)存中,根據(jù)Ember的命名規(guī)則會自動生成一個與路由同名的控制器,
為了驗證這個說法,打開瀏覽器的控制臺,在打開標(biāo)簽“Ember”然后點擊左側(cè)的“/# Routes”,找到路由libraries這一塊,可以看到如下截圖的信息。

可以看到每個路由都對應(yīng)著一個同名的控制器。

等待項目重啟完畢,開始驗證代碼是否實現(xiàn)了所設(shè)想的要求。
首先在新增頁面輸入如下截圖信息,然后點擊按鈕保存數(shù)據(jù)。

稍等片刻,等待數(shù)據(jù)保存完畢,可以看到界面順利跳轉(zhuǎn)到了http://localhost:4200/libraries下,如下圖所示,并且看到了剛剛新增的數(shù)據(jù),為了驗證數(shù)據(jù)是否真的保存到服務(wù)器中,我們進(jìn)入到firebase的APP中查看,可以看到數(shù)據(jù)以及保存到里library下。

library數(shù)據(jù)列表頁面截圖

firebase上保存的library數(shù)據(jù)截圖

此時,如果你注釋了方法willTransition()結(jié)果會是怎么樣的呢??!如果沒有這個方法去重置model,當(dāng)你每次在“Add new”頁面輸入輸入并且沒有點擊“Add to library list”保存數(shù),然后切換到其他路由下(比如點擊“List all”切換到路由libraries下)會自動保存一條數(shù)據(jù)到服務(wù)器。

在“Add new”頁面輸入如下截圖數(shù)據(jù)

點擊按鈕“List all”切換到路由libraries下,可以看到在“Add new”頁面添加的數(shù)據(jù),如下圖所示,但是如果你手動刷新頁面后可以發(fā)現(xiàn)這條數(shù)據(jù)不見了,并且在firebase上也沒有這條數(shù)據(jù),可見這條數(shù)據(jù)僅僅是保存到Ember的store中,并沒有真正保存到服務(wù)器上。這樣的體驗是非常糟糕的??!

其中,實現(xiàn)重置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();
  }
}

本篇的內(nèi)容到此全部介紹完畢!本篇我們實現(xiàn)了數(shù)據(jù)的保存、顯示,特別是library數(shù)據(jù)的保存。數(shù)據(jù)的保存、顯示都需要與模型關(guān)聯(lián),模型在Ember是一個非常重要的內(nèi)容!希望讀者好好掌握模型。

家庭作業(yè)

下面兩個作業(yè)完成其中之一即可。本篇選擇第一個,第二個請讀者自行完成!動手才是真理。

增強(qiáng)contact的功能

創(chuàng)建一個包括兩個屬性emailmessage的模型contact,參考代碼

修改路由app/routes/contact.js返回一個空對象到模板上,參考代碼

修改控制器contact.js,保存數(shù)據(jù)到firebase,參考代碼

把放在控制器中的校驗代碼移動到模型app/models/contact.js中,參考代碼

創(chuàng)建一個管理contact的后臺頁面http://localhost:4200/admin/contacts,參考代碼

在項目首頁的導(dǎo)航菜單上增加一個菜單項“Contacts”,點擊菜單進(jìn)入http://localhost:4200/admin/contact,參考代碼

使用表格展示所有的contact數(shù)據(jù),參考代碼

使用路由和模型重構(gòu)有關(guān)contact的代碼

把有關(guān)contact的檢驗放到模型類中

把控制器contact.js中保存數(shù)據(jù)的代碼移動到同名的路由中

測試通過后刪除控制器contact.js

作業(yè)演示結(jié)果

當(dāng)輸入的郵箱格式正確,并且message長度大于6時按鈕“send”才可用。

保存成功后情況輸入框,并且顯示提示信息。當(dāng)切換路由后再進(jìn)入到http://localhost:4200/contact會清空保存成功的提示信息。

后臺頁面成功顯示了新增的數(shù)據(jù),即使手動刷新頁面數(shù)據(jù)也不會丟失,可見數(shù)據(jù)已經(jīng)保存到firebase,在此不再貼firebase上的數(shù)據(jù)截圖了!



為了照顧懶人我把完整的代碼放在GitHub上,如有需要請參考參考。博文經(jīng)過多次修改,博文上的代碼與github代碼可能有出入,不過影響不大!如果你覺得博文對你有點用,請在github項目上給我點個star吧。您的肯定對我來說是最大的動力?。?/p>

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79521.html

相關(guān)文章

  • 理解CKB的Cell模型

    摘要:交易依然表示狀態(tài)的變化遷移。這樣一個模型的特點是狀態(tài)是第一性的所有者是狀態(tài)的屬性,每一份狀態(tài)只有一個所有者狀態(tài)不斷的被銷毀和創(chuàng)建。值得指出的是,的編程模型之所以強(qiáng)大,更多是因為它有狀態(tài),而不是因為它的有限圖靈完備。 在設(shè)計 CKB 的時候,我們想要解決三個方面的問題: 狀態(tài)爆炸引起的公地悲劇及去中心化的喪失;計算和驗證耦合在了一起使得無論是計算還是驗證都失去了靈活性,難以擴(kuò)展;交易與價...

    henry14 評論0 收藏0
  • 對比特幣的繼承與創(chuàng)新!深入理解公鏈 CKB 的 Cell 模型

    摘要:為了理解底層公鏈的模型,我們前置了幾篇概念性文章,講述了我們應(yīng)該以狀態(tài)為中心設(shè)計區(qū)塊鏈系統(tǒng)的,以及這么做帶來的好處。交易依然表示狀態(tài)的變化遷移。 為了理解底層公鏈 CKB 的 Cell 模型,我們前置了幾篇概念性文章,講述了我們應(yīng)該以狀態(tài)為中心設(shè)計區(qū)塊鏈系統(tǒng)的,以及這么做帶來的好處。并且在上一篇文章中,詳細(xì)分析了比特幣 UTXO 模型和以太坊的 Account 模型,以及進(jìn)行了對比分析...

    ruicbAndroid 評論0 收藏0
  • 胡扯JS系列-內(nèi)存模型和函數(shù)執(zhí)行

    摘要:二在中函數(shù)是如何執(zhí)行的函數(shù)我們之前已經(jīng)都接觸過了,函數(shù)無非有兩部分?jǐn)?shù)據(jù)和對數(shù)據(jù)的操作。函數(shù)的調(diào)用輸出結(jié)果為我們使用了的調(diào)試,函數(shù)在執(zhí)行時會將參數(shù)和函數(shù)中所用到的變量方法相同的地位,即在函數(shù)內(nèi)部執(zhí)行的時候不會區(qū)分是參數(shù)還是變量。 showImg(https://segmentfault.com/img/remote/1460000017790532); 準(zhǔn)備寫點亂七八糟的文章,對Java...

    douzifly 評論0 收藏0
  • tensorflow用cpu訓(xùn)練

    好的,下面是一篇關(guān)于使用CPU訓(xùn)練TensorFlow的編程技術(shù)文章: TensorFlow是一種非常流行的機(jī)器學(xué)習(xí)框架,它可以用于訓(xùn)練各種深度學(xué)習(xí)模型。雖然通常使用GPU進(jìn)行訓(xùn)練,但在某些情況下,使用CPU進(jìn)行訓(xùn)練可能更加適合。本文將介紹如何使用CPU訓(xùn)練TensorFlow,并提供一些編程技巧。 1. 確認(rèn)TensorFlow版本 首先,您需要確認(rèn)您正在使用的TensorFlow版本是否...

    pekonchan 評論0 收藏2185
  • 與時俱進(jìn)的全新設(shè)計:Cell 模型

    摘要:使用模型的代表是比特幣。每一個比特幣全節(jié)點都會維護(hù)當(dāng)前所有的集合,這個集合我們就稱為比特幣賬本的當(dāng)前狀態(tài)即當(dāng)前的賬本。 本文是對前幾期秘猿區(qū)塊鏈課堂中關(guān)于 Cell 模型的總結(jié)。底層公鏈 CKB 的 Cell 模型是一個高度抽象的模型,事實上,你不僅可以在 Cell 上實現(xiàn) First-class Asset,也可以在 Cell 上模擬 Account。通過本文的介紹我們可以看出,Ce...

    CloudDeveloper 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<