02.對象Objects

對象

1.Parse.Object

在Parse上使用Parse.Object存儲數(shù)據(jù)沮翔。每個Parse.Object都包含與JSON兼容的鍵值對囤踩。這些數(shù)據(jù)是無模式的嘉竟,這意味著您不需要提前指定每個Parse.Object上存在什么key彤守。您只需設(shè)置任何所需的鍵值對凭疮,后端就會存儲它。

例如膛腐,假設(shè)您正在跟蹤游戲的高分睛约。一個Parse.Object可以包含:

score: 1337, playerName: "Sean Plott", cheatMode: false

鍵名必須是字母數(shù)字字符串鼎俘。值可以是字符串哲身、數(shù)字、布爾值贸伐,甚至數(shù)組和字典——可以進行JSON編碼的任何值勘天。

每個Parse.Object都是具有類名的特定子類的實例,您可以使用它來區(qū)分不同類型的數(shù)據(jù)。例如脯丝,我們可以叫高分對象為GameScore商膊。為了保持你的代碼看起來漂亮,我們建議您使用如下命名方式:NameYourClassesLikeThis和nameYourKeysLikeThis宠进。

要創(chuàng)建一個新的子類晕拆,請使用Parse.Object.extend方法。任何Parse.Query操作都將返回與Parse.Object具有相同類名的新類實例材蹬。如果你熟悉Backbone.Model实幕,那么你已經(jīng)知道如何使用Parse.Object了。它被設(shè)計為以相同的方式創(chuàng)建和修改對象堤器。

// Simple syntax to create a new subclass of Parse.Object.
var GameScore = Parse.Object.extend("GameScore");

// Create a new instance of that class.
var gameScore = new GameScore();

// Alternatively, you can use the typical Backbone syntax.
var Achievement = Parse.Object.extend({
  className: "Achievement"
});

您可以向Parse.Object的子類添加其他方法和屬性昆庇。

// A complex subclass of Parse.Object
var Monster = Parse.Object.extend("Monster", {
  // Instance methods
  hasSuperHumanStrength: function () {
    return this.get("strength") > 18;
  },
  // Instance properties go in an initialize method
  initialize: function (attrs, options) {
    this.sound = "Rawr"
  }
}, {
  // Class methods
  spawn: function(strength) {
    var monster = new Monster();
    monster.set("strength", strength);
    return monster;
  }
});

var monster = Monster.spawn(200);
alert(monster.get('strength'));  // Displays 200.
alert(monster.sound); // Displays Rawr.

要創(chuàng)建任何Parse Object類的單個實例,還可以直接使用Parse.Object構(gòu)造函數(shù)闸溃。new Parse.Object(className)將使用該類名創(chuàng)建一個單獨的Parse對象整吆。

如果您已經(jīng)在代碼庫中使用ES6,好消息辉川!從1.6.0版起表蝙,JavaScript SDK與ES6類兼容。您可以使用extends關(guān)鍵字對Parse.Object進行子類化:

class Monster extends Parse.Object {
  constructor() {
    // Pass the ClassName to the Parse.Object constructor
    super('Monster');
    // All other initialization
    this.sound = 'Rawr';
  }

  hasSuperHumanStrength() {
    return this.get('strength') > 18;
  }

  static spawn(strength) {
    var monster = new Monster();
    monster.set('strength', strength);
    return monster;
  }
}

但是员串,在使用extends時勇哗,SDK不會自動識別您的子類。如果您希望從查詢返回的對象使用您的Parse.Object子類寸齐,則需要注冊該子類欲诺,類似于我們在其他平臺上執(zhí)行的操作。

// After specifying the Monster subclass...
Parse.Object.registerSubclass('Monster', Monster);

2.保存對象

假設(shè)您想把上述的GameScore保存到Parse Cloud中渺鹦。接口類似于一個包含save方法的Backbone.Model:

var GameScore = Parse.Object.extend("GameScore");
var gameScore = new GameScore();

gameScore.set("score", 1337);
gameScore.set("playerName", "Sean Plott");
gameScore.set("cheatMode", false);

gameScore.save(null, {
  success: function(gameScore) {
    // Execute any logic that should take place after the object is saved.
    alert('New object created with objectId: ' + gameScore.id);
  },
  error: function(gameScore, error) {
    // Execute any logic that should take place if the save fails.
    // error is a Parse.Error with an error code and message.
    alert('Failed to create new object, with error code: ' + error.message);
  }
});

在這段代碼運行之后扰法,你可能想知道是否確實產(chǎn)生了什么效果。為了確保數(shù)據(jù)已被保存毅厚,您可以在Parse中查看應(yīng)用程序的數(shù)據(jù)瀏覽器塞颁。可以看到這樣的內(nèi)容:

objectId: "xWMyZ4YEGZ", score: 1337, playerName: "Sean Plott", cheatMode: false,
createdAt:"2011-06-10T18:33:42Z", updatedAt:"2011-06-10T18:33:42Z"

這里需要注意兩點吸耿。在運行此代碼之前祠锣,您不必配置或設(shè)置一個新的GameScore類。您的Parse應(yīng)用程序在首次碰到時咽安,就會直接創(chuàng)建此類伴网。

還有一些為了使用方便而建立的字段,是不需要指定其值的:

  • objectId是每個已保存對象的唯一標識符妆棒。
  • createdAt和updatedAt表示每個對象在云端創(chuàng)建和上次修改的時間澡腾。

每個這些字段都由Parse填充沸伏,所以直到保存操作完成前,他們在Parse.Object中并不存在动分。

如果您愿意毅糟,您可以在調(diào)用save中直接設(shè)置這些屬性。

var GameScore = Parse.Object.extend("GameScore");
var gameScore = new GameScore();

gameScore.save({
  score: 1337,
  playerName: "Sean Plott",
  cheatMode: false
}, {
  success: function(gameScore) {
    // The object was saved successfully.
  },
  error: function(gameScore, error) {
    // The save failed.
    // error is a Parse.Error with an error code and message.
  }
});

3.檢索對象

將數(shù)據(jù)保存到云端很有趣澜公,但再次獲取這些數(shù)據(jù)更為有趣姆另。如果你有objectId,你可以使用Parse.Query檢索整個Parse.Object:

var GameScore = Parse.Object.extend("GameScore");
var query = new Parse.Query(GameScore);
query.get("xWMyZ4YEGZ", {
  success: function(gameScore) {
    // The object was retrieved successfully.
  },
  error: function(object, error) {
    // The object was not retrieved successfully.
    // error is a Parse.Error with an error code and message.
  }
});

要獲取值Parse.Object坟乾,可使用get方法蜕青。

var score = gameScore.get("score");
var playerName = gameScore.get("playerName");
var cheatMode = gameScore.get("cheatMode");

這三個特殊保留值作為屬性,是不能使用'get'方法檢索糊渊,也不能使用'set'方法進行修改:

var objectId = gameScore.id;
var updatedAt = gameScore.updatedAt;
var createdAt = gameScore.createdAt;

如果您需要刷新已有的對象在Parse Cloud中的最新數(shù)據(jù)右核,則可以調(diào)用fetch方法:

myObject.fetch({
  success: function(myObject) {
    // The object was refreshed successfully.
  },
  error: function(myObject, error) {
    // The object was not refreshed successfully.
    // error is a Parse.Error with an error code and message.
  }
});

4.更新對象

更新對象很簡單。只需設(shè)置一些新的數(shù)據(jù)渺绒,并調(diào)用save方法贺喝。例如:

// Create the object.
var GameScore = Parse.Object.extend("GameScore");
var gameScore = new GameScore();

gameScore.set("score", 1337);
gameScore.set("playerName", "Sean Plott");
gameScore.set("cheatMode", false);
gameScore.set("skills", ["pwnage", "flying"]);

gameScore.save(null, {
  success: function(gameScore) {
    // Now let's update it with some new data. In this case, only cheatMode and score
    // will get sent to the cloud. playerName hasn't changed.
    gameScore.set("cheatMode", true);
    gameScore.set("score", 1338);
    gameScore.save();
  }
});

Parse會自動計算出哪些數(shù)據(jù)已更改,因此只有“臟”字段才會發(fā)送到Parse Cloud宗兼。您不用費心去壓縮不打算更新的數(shù)據(jù)躏鱼。

計數(shù)器

上面的例子是一個常見的用例∫笊埽“score”字段是一個需要不斷更新玩家最新分數(shù)的計數(shù)器染苛。使用上面的方法是有效的,但是它很麻煩主到,如果有多個客戶端嘗試更新同一個計數(shù)器茶行,可能會導致問題。

為了有助于存儲計數(shù)器類型的數(shù)據(jù)登钥,Parse提供了原子增加(或減少)任何數(shù)字字段的方法畔师。所以,同樣的更新可以重寫為:

gameScore.increment("score");
gameScore.save();

您還可以向increment方法傳遞第二個參數(shù)來指定增加任意數(shù)量牧牢。當沒有指定數(shù)量時看锉,默認情況下增加1。

數(shù)組

為了存儲數(shù)組塔鳍,以下三個方法可以用于原子更改與給定鍵相關(guān)聯(lián)的數(shù)組:

  • add:將給定的對象附加到數(shù)組字段的末尾伯铣。
  • addUnique:只有當它不包含在數(shù)組字段中時才添加給定的對象。插入位置不能保證轮纫。
  • remove:從數(shù)組字段中刪除給定對象的所有實例腔寡。

例如,我們可以將項目添加到類似“skills”字段的集合中蜡感,如下所示:

gameScore.addUnique("skills", "flying");
gameScore.addUnique("skills", "kungfu");
gameScore.save();

請注意蹬蚁,目前不能在同一次保存中從數(shù)組中原子添加和刪除項目。您必須在不同類型的數(shù)組操作之間調(diào)用save郑兴。

5.銷毀對象

要從云中刪除對象:

myObject.destroy({
  success: function(myObject) {
    // The object was deleted from the Parse Cloud.
  },
  error: function(myObject, error) {
    // The delete failed.
    // error is a Parse.Error with an error code and message.
  }
});

您可以使用unset方法從對象中刪除單個字段:

// After this, the playerName field will be empty
myObject.unset("playerName");

// Saves the field deletion to the Parse Cloud.
// If the object's field is an array, call save() after every unset() operation.
myObject.save();

請注意犀斋,不推薦使用object.set(null)從對象中刪除字段,因為它將導致意想不到的結(jié)果情连。

6.關(guān)系數(shù)據(jù)

對象可能與其他對象有關(guān)系叽粹。例如沽甥,在博客應(yīng)用程序中叛赚,一個Post對象可能有很多Comment對象。Parse支持各種關(guān)系赘艳,包括一對一挽拔,一對多和多對多辆脸。

一對一和一對多關(guān)系

一對一和一對多關(guān)系都通過將一個Parse.Object作為值保存到另一個對象中來建模。例如螃诅,博客應(yīng)用中的每個Comment都有一個Post與之對應(yīng)啡氢。

要創(chuàng)建包含單個Comment的新Post對象,可以這樣寫:

// Declare the types.
var Post = Parse.Object.extend("Post");
var Comment = Parse.Object.extend("Comment");

// Create the post
var myPost = new Post();
myPost.set("title", "I'm Hungry");
myPost.set("content", "Where should we go for lunch?");

// Create the comment
var myComment = new Comment();
myComment.set("content", "Let's do Sushirrito.");

// Add the post as a value in the comment
myComment.set("parent", myPost);

// This will save both myPost and myComment
myComment.save();

在內(nèi)部术裸,Parse框架將會把引用對象存儲在同一個位置倘是,以保持一致性。你也可以使用objectId來鏈接對象袭艺,如:

var post = new Post();
post.id = "1zEcyElZ80";

myComment.set("parent", post);

默認情況下搀崭,當獲取對象時,Parse.Object不會獲取相關(guān)的對象猾编。這些對象的值無法檢索到瘤睹,直到它們被這樣讀取:

var post = fetchedComment.get("parent");
post.fetch({
  success: function(post) {
    var title = post.get("title");
  }
});

多對多關(guān)系

使用Parse.Relation為多對多關(guān)系建模答倡。除了您不需要一次獲取關(guān)系中的所有對象默蚌,這個過程類似于將Parse.Object數(shù)組存儲在一個鍵中。此外苇羡,Parse.Relation允許擴展比Parse.Object數(shù)組方法更多的對象绸吸。例如,一個User可能會喜歡許多Posts设江。在這種情況下锦茁,你可以使用relation存儲一個User喜歡的一組Posts。為了添加一個Post到User的“l(fā)ikes”列表中叉存,你可以這樣做:

var user = Parse.User.current();
var relation = user.relation("likes");
relation.add(post);
user.save();

您可以從Parse.Relation的刪除帖子:

relation.remove(post);
user.save();

您可以在調(diào)用save之前码俩,調(diào)用add和remove多次:

relation.remove(post1);
relation.remove(post2);
user.save();

您也可以傳入一個Parse.Object數(shù)組來add和remove:

relation.add([post1, post2, post3]);
user.save();

默認情況下,此關(guān)系中的對象列表未下載歼捏「宕妫可以通過query返回的Parse.Query獲取用戶喜歡的帖子列表笨篷。代碼如下:

relation.query().find({
  success: function(list) {
    // list contains the posts that the current user likes.
  }
});

如果你只想要帖子的一個子集,可以在query返回的Parse.Query上添加額外的約束:

var query = relation.query();
query.equalTo("title", "I'm Hungry");
query.find({
  success:function(list) {
    // list contains post liked by the current user which have the title "I'm Hungry".
  }
});

有關(guān)Parse.Query的詳細信息瓣履,請參閱本指南的查詢(queries)部分率翅。一個Parse.Relation的行為類似于用于查詢目的的Parse.Object數(shù)組,所以在Parse.Object數(shù)組上能執(zhí)行的查詢都可以在Parse.Relation上執(zhí)行袖迎。

7.數(shù)據(jù)類型

到目前為止冕臭,我們已經(jīng)使用了值類型String,Number和Parse.Object燕锥。Parse也支持Dates和null辜贵。您可以嵌套JSON Objects和JSON Arrays以在單個Parse.Object中存儲更多的結(jié)構(gòu)化數(shù)據(jù)」樾危總的來說托慨,對象中的每個字段允許使用以下類型:

  • String => String
  • Number => Number
  • Bool => bool
  • Array => JSON Array
  • Object => JSON Object
  • Date => Date
  • File => Parse.File
  • Pointer => 其他 Parse.Object
  • Relation => Parse.Relation
  • Null => null

一些例子:

var number = 42;
var bool = false;
var string = "the number is " + number;
var date = new Date();
var array = [string, number];
var object = { number: number, string: string };
var pointer = MyClassName.createWithoutData(objectId);

var BigObject = Parse.Object.extend("BigObject");
var bigObject = new BigObject();
bigObject.set("myNumber", number);
bigObject.set("myBool", bool);
bigObject.set("myString", string);
bigObject.set("myDate", date);
bigObject.set("myArray", array);
bigObject.set("myObject", object);
bigObject.set("anyKey", null); // this value can only be saved to an existing key
bigObject.set("myPointerKey", pointer); // shows up as Pointer <MyClassName> in the Data Browser
bigObject.save();

我們不建議存儲大量二進制數(shù)據(jù),如圖像或文檔Parse.Object暇榴。Parse.Objects不應(yīng)超過128KB榴芳。我們建議您使用Parse.Files存儲圖像、文檔和其他類型的文件跺撼。您可以通過實例化一個Parse.File對象并將其設(shè)置在字段上來實現(xiàn)窟感。有關(guān)詳細信息,請參閱文件部分歉井。

有關(guān)Parse如何處理數(shù)據(jù)的更多信息柿祈,請查看我們文檔的數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哩至,一起剝皮案震驚了整個濱河市躏嚎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌菩貌,老刑警劉巖卢佣,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異箭阶,居然都是意外死亡虚茶,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門仇参,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嘹叫,“玉大人,你說我怎么就攤上這事诈乒≌稚龋” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵怕磨,是天一觀的道長喂饥。 經(jīng)常有香客問我消约,道長,這世上最難降的妖魔是什么员帮? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任或粮,我火速辦了婚禮,結(jié)果婚禮上集侯,老公的妹妹穿的比我還像新娘。我一直安慰自己帜消,他們只是感情好棠枉,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著泡挺,像睡著了一般辈讶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娄猫,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天贱除,我揣著相機與錄音,去河邊找鬼媳溺。 笑死月幌,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的悬蔽。 我是一名探鬼主播扯躺,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蝎困!你這毒婦竟也來了录语?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤禾乘,失蹤者是張志新(化名)和其女友劉穎澎埠,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體始藕,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蒲稳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了伍派。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弟塞。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拙已,靈堂內(nèi)的尸體忽然破棺而出决记,到底是詐尸還是另有隱情,我是刑警寧澤倍踪,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布系宫,位于F島的核電站索昂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏扩借。R本人自食惡果不足惜椒惨,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望潮罪。 院中可真熱鬧康谆,春花似錦、人聲如沸嫉到。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽何恶。三九已至孽锥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間细层,已是汗流浹背惜辑。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留疫赎,地道東北人盛撑。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像捧搞,于是被迫代替她去往敵國和親撵彻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容