【问题标题】:Array stringified but not operational in TypeScript / javascript数组字符串化但在 TypeScript / javascript 中不可操作
【发布时间】:2017-05-12 13:41:01
【问题描述】:

使用正确的结构(包括数组)生成一个字符串。我可以在 http://jsonviewer.stack.hu/ 等网站中浏览 JSON

但是当我尝试访问数组时,数组本身为空。

这是我的情况:

首先是接口:

export interface IPlayerJSON {
    idPlayer: number,
    name: string;
    email: string,
    arrayAvatar: Array<IAvatarJSON>,
};

export interface IAvatarJSON {
    idAvatar: number,
    nickName: string,
    original: boolean,
    signature: string,
};

然后是被覆盖的方法

public toJSON(): IPlayerJSON {
        let json: IPlayerJSON;
        json = {idPlayer: this.idPlayer, email: this.email, name: this.name, avatarOriginal: this.avatarOriginal.toJSON(),
               arrayAvatar: []}
        for (let r of this.arrayAvatar) {
            json.arrayAvatar.push(r.toJSON());
        };
        return json;
    };

Avatar 也有一个修改后的 toJSON。正如我所说,JSON.stringify 会生成正确且可导航的 JSON。

当我尝试补充水分时:

public static playerRehydrate(json: IPlayerJSON): Player {
        let player : Player = new Player(null, null, null);
        console.log('JSON ', json); // perfect, with array
        player.setEmail(json.email);
        player.setPlayerID(json.idPlayer);
        player.setName(json.name);
        console.log('Array Avatar ', json.arrayAvatar);
        for (let r of json.arrayAvatar) { // throw error, no lenght of undefined
            player.addAvatar(RehydrateService.avatarRehydrate(r));
        };
        return player;
    };

json.arrayAvatar 为空,我无法通过它进行交互。

有什么建议吗?谢谢

【问题讨论】:

  • 查看输出 json 以及从日志行 Array Avatar 获得的内容会有所帮助。
  • IPlayerJSON 没有 avatarOriginal 但您将其添加到 toJSON

标签: javascript arrays json typescript


【解决方案1】:

好的,我错过了这个过程中的一个步骤。

正确的是:

let player: Player;
let txt: string = JSON.stringify(player); // here all the toJSON() chain will be called
let playerJSON: IPlayerJSON = JSON.parse(txt); // <-- here is the missing code
player = playerRehydrate(playerJSON); // now player has state and behaviour

【讨论】:

  • 是的,您在原始问题中没有使用 JSON.stringify 提及任何内容。
【解决方案2】:

您发布的代码works on its own in the playground,因此您的问题一定出在其他地方的其他代码中。 (无法作为评论发布,因为带有源代码的 Playground 链接太长。)

interface IPlayerJSON {
    idPlayer: number,
    name: string;
    email: string,
    arrayAvatar: Array<IAvatarJSON>,
}

interface IAvatarJSON {
    idAvatar: number,
    nickName: string,
    original: boolean,
    signature: string,
}

class Avatar {
  constructor(
    public idAvatar: number,
    public nickName: string,
    public original: boolean,
    public signature: string
  ) {

  }
  public toJSON(): IAvatarJSON {
    const { idAvatar, nickName, original, signature } = this;
    return { idAvatar, nickName, original, signature };
  }
}

class Player {
  constructor(
    public idPlayer: number,
    public email: string,
    public name: string,
    public avatarOriginal: Avatar = null,
    public arrayAvatar: Avatar[] = []
  ) {

  }
  public setEmail(email: string) {
    this.email = email;
  }
  public setPlayerID(idPlayer: number) {
    this.idPlayer = idPlayer;
  }
  public setName(name: string) {
    this.name = name;
  }
  public addAvatar(avatar: Avatar) {
    this.arrayAvatar.push(avatar);
  }
  public toJSON(): IPlayerJSON {
    let json: IPlayerJSON;
    json = {
      idPlayer: this.idPlayer, email: this.email, name: this.name,
      // avatarOriginal: this.avatarOriginal.toJSON(), 
      arrayAvatar: []
    }
    for (let r of this.arrayAvatar) {
      json.arrayAvatar.push(r.toJSON());
    };
    return json;
  }
}

class RehydrateService {
    public static playerRehydrate(json: IPlayerJSON): Player {
      let player: Player = new Player(null, null, null);
      console.log('JSON in rehydrate', json); // perfect, with array
      player.setEmail(json.email);
      player.setPlayerID(json.idPlayer);
      player.setName(json.name);
      console.log('Array Avatar in rehydrate', json.arrayAvatar);
      for (let r of json.arrayAvatar) { // throw error, no lenght of undefined
          player.addAvatar(RehydrateService.avatarRehydrate(r));
      };
      return player;
  };
  public static avatarRehydrate(json: IAvatarJSON): Avatar {
    return new Avatar(json.idAvatar, json.nickName, json.original, json.signature);
  }
}

const player: Player = new Player(1, "@", "a",
  new Avatar(2, "b", true, "bb"),
  [
    new Avatar(3, "c", false, "cc"),
    new Avatar(4, "d", false, "dd"),
    new Avatar(5, "e", false, "ee")
  ]
);

console.log("player source:", player)
console.log("player to JSON result:", player.toJSON())
console.log("rehydrate player JSON result:", RehydrateService.playerRehydrate(player.toJSON()))

toJSON 和 rehydrate 之后的最后一条日志语句的输出包括头像数组:

这表明您可以遍历头像数组:

RehydrateService.playerRehydrate(player.toJSON()).arrayAvatar.forEach(avatar => console.log(avatar))

【讨论】:

  • 是的,但是如果您尝试在数组中导航,它会给您一个错误。所以需要在 rehydrate 方法的结果中添加 JSON.parse。
  • 不是这样,至少不是发布的代码。我看到您添加了一个答案,其中包含 JSON.stringify 未在原始问题中显示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-19
  • 1970-01-01
  • 2016-07-18
  • 1970-01-01
  • 2018-04-02
  • 2020-09-04
相关资源
最近更新 更多