Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在保存之前查询CloudCode中的对象?_Javascript_Parse Platform_Parse Cloud Code_Before Save - Fatal编程技术网

Javascript 如何在保存之前查询CloudCode中的对象?

Javascript 如何在保存之前查询CloudCode中的对象?,javascript,parse-platform,parse-cloud-code,before-save,Javascript,Parse Platform,Parse Cloud Code,Before Save,我试图使用CloudCode-beforeSave函数将新对象与原始对象进行比较。我需要将更新中发送的字段与现有值进行比较。问题是我无法正确获取对象。当我运行查询时,我总是从发送的对象获取值 更新:我尝试了另一种方法,可以获取旧寄存器(已保存在parse中的寄存器)但是请求中发送的新请求被旧请求覆盖。什么?!另一个问题是,即使代码发送了响应.success(),更新也没有保存。 我相信我在这里遗漏了一些非常明显的东西。或者我正面临着一个虫子什么的 新方法 Parse.Cloud.beforeSa

我试图使用CloudCode-beforeSave函数将新对象原始对象进行比较。我需要将更新中发送的字段与现有值进行比较。问题是我无法正确获取对象。当我运行查询时,我总是从发送的对象获取值

更新:我尝试了另一种方法,可以获取旧寄存器(已保存在parse中的寄存器)但是请求中发送的新请求被旧请求覆盖。什么?!另一个问题是,即使代码发送了
响应.success()
,更新也没有保存。 我相信我在这里遗漏了一些非常明显的东西。或者我正面临着一个虫子什么的

新方法

Parse.Cloud.beforeSave('Tasks', function(request, response) {
  if ( !request.object.isNew() )
  {
    var Task = Parse.Object.extend("Tasks");
    var newTask = request.object;
    var oldTask = new Task();
    oldTask.set("objectId", request.object.id);
    oldTask.fetch()
        .then( function( oldTask )
    {
        console.log(">>>>>> Old Task: " + oldTask.get("name") + " version: " + oldTask.get("version"));
        console.log("<<<<<< New Task: " + newTask.get("name") + " version: " + newTask.get("version"));
        response.success();
    }, function( error ) {
            response.error( error.message );
        }
    );
    }
});
注意:我正在通过cURL和解析控制台测试登录

CloudCode在保存之前

Parse.Cloud.beforeSave("Tasks", function( request, response) {
  var query = new Parse.Query("Tasks");
  query.get(request.object.id)
    .then(function (oldObj) {
        console.log("-------- OLD Task: " + oldObj.get("name") + " v: " + oldObj.get("version"));
        console.log("-------- NEW Task: " + request.object.get("name") + " v: " + request.object.get("version"));
    }).then(function () {
        response.success();
    }, function ( error) {
        response.error(error.message);
    }
  );
});
"updatedAt": "2015-10-02T19:45:47.104Z"
卷曲请求

curl -X PUT \
-H "Content-Type: application/json" \
-H "X-Parse-Application-Id: xxxxx" \
-H "X-Parse-REST-API-Key: xxxxx" \
-H "X-Parse-Session-Token: xxxx" \
-d "{\"name\":\"NEW_VALUE\", \"version\":9999}" \
https://api.parse.com/1/classes/Tasks/VlJdk34b2A
JSON响应

Parse.Cloud.beforeSave("Tasks", function( request, response) {
  var query = new Parse.Query("Tasks");
  query.get(request.object.id)
    .then(function (oldObj) {
        console.log("-------- OLD Task: " + oldObj.get("name") + " v: " + oldObj.get("version"));
        console.log("-------- NEW Task: " + request.object.get("name") + " v: " + request.object.get("version"));
    }).then(function () {
        response.success();
    }, function ( error) {
        response.error(error.message);
    }
  );
});
"updatedAt": "2015-10-02T19:45:47.104Z"
日志 日志打印原始值和新值,但我也不知道如何访问它

I2015-10-02T19:57:08.603Z]v160 before_save triggered for Tasks for user tAQf1nCWuz:
Input: {"original":{"createdAt":"2015-10-02T17:47:34.143Z","name":"OLD_VALUE","objectId":"VlJdk34b2A","updatedAt":"2015-10-02T19:45:47.104Z","version":0},"update":{"name":"NEW_VALUE","version":9999}}
Result: Update changed to {"name":"NEW_VALUE","version":9999}
I2015-10-02T19:57:08.901Z]-------- OLD Task: NEW_VALUE v: 9999
I2015-10-02T19:57:08.902Z]-------- NEW Task: NEW_VALUE v: 9999

与执行查询不同,您可以通过检查哪些键是脏的来查看修改的属性,这意味着它们已经更改但尚未保存

JSSDK包括
dirtyKeys()
,它返回已更改的密钥。试试这个

var attributes = request.object.attributes; 
var changedAttributes = new Array(); 

for(var attribute in attributes) {

    if(object.dirty(attribute)) { 
        changedAttributes.push(attribute);
        // object.get(attribute) is changed and the key is pushed to the array
    }
}

为了澄清,要获取原始属性的值,您必须调用
get()
来加载这些预保存值。需要注意的是,这将被视为另一个API请求。

如果我是您,我会将旧值作为参数传递给云函数,以便您可以在request.params(参数名称)下访问它。我不相信有其他方法可以得到旧的价值。一个古老的SO问题说您可以使用.get(),但您声称这不起作用。除非你的版本里已经有9999了


编辑-我想beforeSave不像普通函数那样被调用。。。那么,创建一个“更新版本”函数,该函数传入当前任务和您试图更新到的版本,也许

经过大量的测试和错误,我可以弄清楚到底发生了什么

事实证明,解析正在将具有相同类和id的任何对象合并到一个实例中。这就是为什么我总是让对象在DB中注册,或者由用户发送。我真的无法理解这种行为,但无论如何

Parse javascript sdk提供了一个名为
Parse.Object.disableSingeInstance
的方法,该方法禁用此“功能”。但是,一旦调用了该方法,所有已经定义的对象都是未定义的。其中包括已发送的对象。Witch意味着您既不能保存已发送的对象,也不能为以后的引用保存该对象

唯一的选择是保存发送的obj的键和值,然后重新创建。因此,我需要在调用
disableSingleInstance
之前捕获请求,将其转换为JSON,然后禁用singleinstance,获取保存在DB中的对象,并使用保存的JSON重新创建发送的对象

它并不漂亮,也肯定不是最有效的代码,但我找不到其他方法。如果有人有别的办法,一定要告诉我

Parse.Cloud.beforeSave('Tasks', function(request, response) {
  if ( !request.object.isNew() ) {
    var id = request.object.id;
    var jsonReq;
    var Task = Parse.Object.extend("Tasks");
    var newTask = new Task;
    var oldTask = new Task;

    // getting new Obj
    var queryNewTask = new Parse.Query(Task);
    queryNewTask.get(id)
        .then(function (result) {
            newTask = result;

            // Saving values as a JSON to later reference
            jsonReq = result.toJSON();

            // Disable the merge of obj w/same class and id
            // It will also undefine all Parse objects,
            // including the one sent in the request
            Parse.Object.disableSingleInstance();

            // getting object saved in DB
            oldTask.set("objectId", id);
            return oldTask.fetch();
        }).then(function (result) {
            oldTask = result;

            // Recreating new Task sent
            for ( key in jsonReq ) {
                newTask.set( key, jsonReq[key]);
            }

            // Do your job here
        }, function (error) {
            response.error( error.message );
        }
    );
  }
});

嘿,这对我来说非常有效:

var dirtyKeys = request.object.dirtyKeys();
var query = new Parse.Query("Question");
var clonedData = null;
        query.equalTo("objectId", request.object.id);
        query.find().then(function(data){
            var clonedPatch = request.object.toJSON();
            clonedData = data[0];
            clonedData = clonedData.toJSON();
            console.log("this is the data : ", clonedData, clonedPatch, dirtyKeys);
            response.success();
        }).then(null, function(err){
            console.log("the error is : ", err);
        });

对于在2021 ish中访问此线程的用户,如果在保存之前在客户端SDK中加载了服务器数据,则可以通过在
save()的
context
选项中从客户端SDK传递服务器数据来解决此问题
函数,然后在
beforeSave
afterSave
云函数中使用它

// eg JS client sdk
const options  = { 
  context: {
    before: doc._getServerData() // object data, as loaded
  } 
}
doc.save(null, options)
警告:如果您没有在客户端的
\u getServerData()
函数中加载属性,那么这对您没有帮助

第二个警告:parse不会在云函数中为您处理(取消)序列化,例如:

{
  before: { // < posted as context
    status: {
      is: 'atRisk',
      comment: 'Its all good now!',
      at: '2021-04-09T15:39:04.907Z', // string
      by: [Object] // pojo
    }
  },
  after: {
    status: { // < posted as doc's save data
      is: 'atRisk',
      comment: 'Its all good now!',
      at: 2021-04-09T15:39:04.907Z, // instanceOf Date
      by: [ParseUser] // instanceOf ParseUser
    }
  }
}
{
之前:{/<作为上下文发布
地位:{
是‘阿斯克’,
评论:“现在一切都好了!”,
at:'2021-04-09T15:39:04.907Z',//字符串
by:[Object]//pojo
}
},
之后:{
状态:{/<作为文档的保存数据过帐
是‘阿斯克’,
评论:“现在一切都好了!”,
时间:2021-04-09T15:39:04.907Z,//日期实例
by:[ParseUser]//ParseUser的实例
}
}
}

我不确定您是否能做到这一点。你这样做的目的是什么?也许我们可以找到一个不同的解决方案。我需要检查注册表的版本,并与请求中发送的版本进行比较。这很奇怪,我真的不明白为什么标记为“新方法”的版本不起作用。。。应该这样。我看到了你关于Parse.Object.disableSingeInstance的说明,但这是我第一次听说。这似乎是非常低效的,因为您必须获取对象两次。我会通过推特或FB联系赫克托并询问此事。@MobileVet我完全同意你的看法。在生产场景中,我的解决方案是不可取的。事实上,这个问题太疯狂了,以至于我都在考虑完全放弃解析。如果这个叫赫克托的家伙是Parse.com的人,你能告诉我他的联系方式吗?也许他能把我从地狱里救出来。@MobileVet我已经有他的联系人了。谢谢你的小费。现在会试着联系他根据解析博客dirtyKey比较有用,用字段被修改了,对吗?但我需要一个特定字段的值。我需要将注册的字段值与请求中的相同字段值进行比较。有一种方法可以用dirtyKey做到这一点吗?刚刚更新了我的帖子来澄清。正确的说法是,
dirtyKey
只能用于告知哪些属性已更改,而不能预先告知键的值。这些必须使用另一个请求获取。Parse不公开JSSDK中的
previousAttributes()
previous(“columnName”)
。对,但是