对象
1.Parse.Object
在Parse上使用Parse.Object存储数据。每个Parse.Object都包含与JSON兼容的键值对。这些数据是无模式的,这意味着您不需要提前指定每个Parse.Object上存在什么key。您只需设置任何所需的键值对,后端就会存储它。
例如,假设您正在跟踪游戏的高分。一个Parse.Object可以包含:
score: 1337, playerName: "Sean Plott", cheatMode: false
键名必须是字母数字字符串。值可以是字符串、数字、布尔值,甚至数组和字典——可以进行JSON编码的任何值。
每个Parse.Object都是具有类名的特定子类的实例,您可以使用它来区分不同类型的数据。例如,我们可以叫高分对象为GameScore。为了保持你的代码看起来漂亮,我们建议您使用如下命名方式:NameYourClassesLikeThis和nameYourKeysLikeThis。
要创建一个新的子类,请使用Parse.Object.extend方法。任何Parse.Query操作都将返回与Parse.Object具有相同类名的新类实例。如果你熟悉Backbone.Model,那么你已经知道如何使用Parse.Object了。它被设计为以相同的方式创建和修改对象。
// 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.
要创建任何Parse Object类的单个实例,还可以直接使用Parse.Object构造函数。new Parse.Object(className)将使用该类名创建一个单独的Parse对象。
如果您已经在代码库中使用ES6,好消息!从1.6.0版起,JavaScript SDK与ES6类兼容。您可以使用extends关键字对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子类,则需要注册该子类,类似于我们在其他平台上执行的操作。
// After specifying the Monster subclass...
Parse.Object.registerSubclass('Monster', Monster);
2.保存对象
假设您想把上述的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);
}
});
在这段代码运行之后,你可能想知道是否确实产生了什么效果。为了确保数据已被保存,您可以在Parse中查看应用程序的数据浏览器。可以看到这样的内容:
objectId: "xWMyZ4YEGZ", score: 1337, playerName: "Sean Plott", cheatMode: false,
createdAt:"2011-06-10T18:33:42Z", updatedAt:"2011-06-10T18:33:42Z"
这里需要注意两点。在运行此代码之前,您不必配置或设置一个新的GameScore类。您的Parse应用程序在首次碰到时,就会直接创建此类。
还有一些为了使用方便而建立的字段,是不需要指定其值的:
- objectId是每个已保存对象的唯一标识符。
- createdAt和updatedAt表示每个对象在云端创建和上次修改的时间。
每个这些字段都由Parse填充,所以直到保存操作完成前,他们在Parse.Object中并不存在。
如果您愿意,您可以在调用save中直接设置这些属性。
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.检索对象
将数据保存到云端很有趣,但再次获取这些数据更为有趣。如果你有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中的最新数据,则可以调用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.更新对象
更新对象很简单。只需设置一些新的数据,并调用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会自动计算出哪些数据已更改,因此只有“脏”字段才会发送到Parse Cloud。您不用费心去压缩不打算更新的数据。
计数器
上面的例子是一个常见的用例。“score”字段是一个需要不断更新玩家最新分数的计数器。使用上面的方法是有效的,但是它很麻烦,如果有多个客户端尝试更新同一个计数器,可能会导致问题。
为了有助于存储计数器类型的数据,Parse提供了原子增加(或减少)任何数字字段的方法。所以,同样的更新可以重写为:
gameScore.increment("score");
gameScore.save();
您还可以向increment方法传递第二个参数来指定增加任意数量。当没有指定数量时,默认情况下增加1。
数组
为了存储数组,以下三个方法可以用于原子更改与给定键相关联的数组:
- add:将给定的对象附加到数组字段的末尾。
- addUnique:只有当它不包含在数组字段中时才添加给定的对象。插入位置不能保证。
- remove:从数组字段中删除给定对象的所有实例。
例如,我们可以将项目添加到类似“skills”字段的集合中,如下所示:
gameScore.addUnique("skills", "flying");
gameScore.addUnique("skills", "kungfu");
gameScore.save();
请注意,目前不能在同一次保存中从数组中原子添加和删除项目。您必须在不同类型的数组操作之间调用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)从对象中删除字段,因为它将导致意想不到的结果。
6.关系数据
对象可能与其他对象有关系。例如,在博客应用程序中,一个Post对象可能有很多Comment对象。Parse支持各种关系,包括一对一,一对多和多对多。
一对一和一对多关系
一对一和一对多关系都通过将一个Parse.Object作为值保存到另一个对象中来建模。例如,博客应用中的每个Comment都有一个Post与之对应。
要创建包含单个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();
在内部,Parse框架将会把引用对象存储在同一个位置,以保持一致性。你也可以使用objectId来链接对象,如:
var post = new Post();
post.id = "1zEcyElZ80";
myComment.set("parent", post);
默认情况下,当获取对象时,Parse.Object不会获取相关的对象。这些对象的值无法检索到,直到它们被这样读取:
var post = fetchedComment.get("parent");
post.fetch({
success: function(post) {
var title = post.get("title");
}
});
多对多关系
使用Parse.Relation为多对多关系建模。除了您不需要一次获取关系中的所有对象,这个过程类似于将Parse.Object数组存储在一个键中。此外,Parse.Relation允许扩展比Parse.Object数组方法更多的对象。例如,一个User可能会喜欢许多Posts。在这种情况下,你可以使用relation存储一个User喜欢的一组Posts。为了添加一个Post到User的“likes”列表中,你可以这样做:
var user = Parse.User.current();
var relation = user.relation("likes");
relation.add(post);
user.save();
您可以从Parse.Relation的删除帖子:
relation.remove(post);
user.save();
您可以在调用save之前,调用add和remove多次:
relation.remove(post1);
relation.remove(post2);
user.save();
您也可以传入一个Parse.Object数组来add和remove:
relation.add([post1, post2, post3]);
user.save();
默认情况下,此关系中的对象列表未下载。可以通过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".
}
});
有关Parse.Query的详细信息,请参阅本指南的查询(queries)部分。一个Parse.Relation的行为类似于用于查询目的的Parse.Object数组,所以在Parse.Object数组上能执行的查询都可以在Parse.Relation上执行。
7.数据类型
到目前为止,我们已经使用了值类型String,Number和Parse.Object。Parse也支持Dates和null。您可以嵌套JSON Objects和JSON Arrays以在单个Parse.Object中存储更多的结构化数据。总的来说,对象中的每个字段允许使用以下类型:
- 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 in the Data Browser
bigObject.save();
我们不建议存储大量二进制数据,如图像或文档Parse.Object。Parse.Objects不应超过128KB。我们建议您使用Parse.Files存储图像、文档和其他类型的文件。您可以通过实例化一个Parse.File对象并将其设置在字段上来实现。有关详细信息,请参阅文件部分。
有关Parse如何处理数据的更多信息,请查看我们文档的数据。