1

首先要做的事情是:我不确定我要提供的信息是否足够,如果需要,我会很乐意添加其他信息。

我正在将一个复杂的结构序列化为 JSON 格式,Field[i][0] 是对对象的“this”引用。

Firebug 在 JSON.Stringify(myObj) 上的输出

萤火虫打印屏幕

只要我将其全部保留为 JS,这一切都很好并且可以工作。但是现在我需要序列化并将其发送到我的后端以获取参考+计算信息。

现在我如何映射回我之前的参考?如何将此引用绑定回对象?这个 $$hash 东西看起来是内部的和专有的,所以我什至没有费心尝试像 Object[$$hash] = ref 之类的东西。

这个一般的想法可能看起来很糟糕,但是结果是异步返回的,我需要一个标识符来将新信息绑定回原始对象。显然,我可以为此编造自己的标识符,但我想知道是否可以选择以这种方式解决它。

编辑

对象是这样创建的(同样)

var arrayOfObj = []

arrayOfObj.push(new Object.With.SomeSettersAndGetters());

Object 有一个类似的方法

function GetRef(){
return this;
}

我用它来通过我的代码保留 ID/Ref。

谢谢!

4

1 回答 1

1

更新

如果您想更新一系列实例并发出许多 Ajax 请求,那么您需要查看 Ajax 长轮询和排队技术。您将无法保留引用,但无论您使用何种 Ajax 技术,都可以使用以下技巧来保留引用。

在顶部添加长轮询,您就可以开始了。

这个想法是这样的:

假设服务器将以 JSON 格式响应。如果您需要参考原始参考资料,这是我的两分钱:

当服务器回复时更新确切的引用。假设您有 10 个实例Something存储在一个数组中。在成功响应时,您可以使用Something类中的方法以您想要的任何方式更新特定实例。

  /**
   * The array with something instances.
   * @type {Array.<Something>}
   */
  var instances = [];

  /**
   * The Ajax success function.
   * @param {Event} event The event object.
   */
  function ajaxSuccess(event) {
       var response = event.target.getResponseText();
       var actualResponse = JSON.parse(response);
       for (var i = 0, len = actualResponse.length; i++) {
           instances[i].setWhatever(actualResponse[i].whatever);
       };
    };

以上是更程序化的方法。如果您想在 JS 中实现全面的 OOP,那么您可以考虑模块化设计模式。假设您有一个将数据加载到某个地方的模块。基本上,与该模块相关的所有内容都是实例属性。

var myModule = function() {
    this.whatever = 1;
};
myModule.prototype.loadMore = function() {
    var request = new XMLHttpRequest(),
        that = this; // store a reference to this.
    request.send(); // etc
    request.onreadystatechange = that.onSucess;
};
myModule.prototype.onSucess = function(event) {
    var response = JSON.parse(event.target.getResponseText());
    this.whatever = response.whatever;

};
var moduleInstance = new myModule();
myModule.loadMore();
// Now the scope is always preserved. The callback function will be executed in the right scope.

让我们假设在事物的后端,您有一个模型类来模仿您的客户端 JavaScript 模型。假设您要更新显示文本的模型中的引用。我在后端使用 Scala,但查看字段/属性并忽略语法。

case class Article (
    title: String,// these are my DB fields for an Article.
    punchline: String,
    content: String,
    author: String
);
// now assume the client is making a request and the server returns the JSON
// for an article. So the reply would be something like:
{"title": "Sample title", "punchline": "whatever", "content": "bla bla bla boring", "author": "Charlie Sheen"};
// when you do 
var response = JSON.parse(event.target.getResponseText());
// response will become a JavaScript object with the exact same properties.
// again, my backend choice is irrelevant.

// Now assume I am inside the success function, which gets called in the same scope
// as the original object, so it refers TO THE SAME THING.
// the trick is to maintain the reference with var that = this.
// otherwise the onSuccess function will be called in global scope.
// now because it's pointing to the same object.
// I can update whatever I want.
this.title = response.title;
this.punchline = response.punchline;
this.content = response.content;
this.author = response.author;
// or I can put it all in a single variable.
this.data = response;

您需要记住的是需要保留范围。这就是诀窍。当我这样做时,var that = this;我复制了对模型实例的引用。引用是通过高阶而不是当前范围记住的。

然后我告诉XMLHttpRequest对象在完成时调用that.ajaxSuccess。因为我使用that了 ,所以ajaxSuccess函数会在当前对象的范围内被调用。所以在ajaxSuccess函数内部,this会指向原来this的,同一个实例。

JavaScript 会在我编写时为我记住它var that = this;

于 2013-04-29T12:02:07.797 回答