加载 JSON 数据
此项目演示两种加载 JSON 数据的方式:从项目中的资源加载,以及通过 HTTP 从远程服务器加载。
从资源加载 JSON
- ESM
- 传统脚本
/**
* @attribute
* @title Character Data
* @type {Asset}
* @resource json
*/
characterData = null;
parseCharacterData(data) {
const names = [];
// Read the character data from the JSON asset and return a list of names
const characters = data.characters;
for (let character of characters) {
names.push(character.firstName + ' ' + character.lastName);
}
return names;
}
//...
// Get JSON data from a project asset
const characterData = this.characterData.resource;
// Parse JSON data
const names = this.parseCharacterData(characterData);
Game.attributes.add('characterData', {
type: 'asset',
assetType: 'json'
});
//...
Game.prototype.parseCharacterData = function (data) {
var names = [];
// Read the character data from the JSON asset and return a list of names
var characters = data.characters;
for (var i = 0; i < characters.length; i++) {
var character = characters[i];
names.push(character.firstName + ' ' + character.lastName);
}
return names;
};
//...
// Get JSON data from a project asset
var characterData = this.characterData.resource;
// Parse JSON data
var names = this.parseCharacterData(characterData);
上面的代码表明,要从项目资源加载 JSON,只需使用 asset 类型的脚本属性,或从资源注册表获取资源,然后访问其 resource 属性。对于 json 类型资源,访问 resource 时,数据已经解析为标准 JavaScript 对象。
得到 JavaScript 对象后,即可照常访问数据,例如像 parseCharacterData 那样遍历属性。
从远程服务器加载 JSON
- ESM
- 传统脚本
async function loadJsonFromRemote(url, callback) {
const res = await fetch(url);
const json = await res.json();
callback(json);
}
//...
// load JSON from a remote server
loadJsonFromRemote("https://api.github.com/", (data) => {
// display JSON data from remote server
el = document.querySelector("#xhr-json");
el.textContent = JSON.stringify(data, null, 4);
});
Game.prototype.loadJsonFromRemote = function (url, callback) {
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function () {
callback(JSON.parse(this.response));
});
xhr.open("GET", url);
xhr.send();
};
//...
// load JSON from a remote server
this.loadJsonFromRemote("https://api.github.com/", function (data) {
// display JSON data from remote server
el = document.querySelector("#xhr-json");
el.textContent = JSON.stringify(data, null, 4);
});
此代码使用标准浏览器 API 中的 XMLHttpRequest 对象,从 URL 请求 JSON 数据,本例请求的是 GitHub API。
收到 "load" 事件后,通过同属标准浏览器 API 的 JSON.parse 解析 JSON 数据,再经由 callback 函数返回结果。
注意,loadJsonFromRemote 是异步调用。
完整代码如下:
- ESM
- 传统脚本
import { Script, createStyle } from 'playcanvas';
export class Game extends Script {
static scriptName = "game";
/**
* @attribute
* @title Display
* @type {Asset}
* @resource html
*/
display = null;
/**
* @attribute
* @title Style
* @type {Asset}
* @resource css
*/
style = null;
/**
* @attribute
* @title Character Data
* @type {Asset}
* @resource json
*/
characterData = null;
// initialize code called once per entity
initialize() {
this.initDisplay();
// Get JSON data from a project asset
const characterData = this.characterData.resource;
// Parse JSON data
const names = this.parseCharacterData(characterData);
// display character names
let el = document.querySelector("#character-name");
if (el) el.textContent = names.join(", ");
// display JSON data from asset
el = document.querySelector("#asset-json");
if (el) el.textContent = JSON.stringify(characterData, null, 4);
// load JSON from a remote server
this.loadJsonFromRemote("https://api.github.com/", (data) => {
// display JSON data from remote server
el = document.querySelector("#xhr-json");
if (el) el.textContent = JSON.stringify(data, null, 4);
});
}
initDisplay() {
const el = createStyle(this.style.resource);
document.head.appendChild(el);
const div = document.createElement("div");
div.setAttribute("id", "container");
div.innerHTML = this.display.resource;
document.body.appendChild(div);
}
parseCharacterData(data) {
const names = [];
// Read the character data from the JSON asset and return a list of names
const characters = data.characters;
for (let character of characters) {
names.push(character.firstName + ' ' + character.lastName);
}
return names;
}
loadJsonFromRemote(url, callback) {
const xhr = new XMLHttpRequest();
xhr.addEventListener("load", function() {
callback(JSON.parse(this.responseText));
});
xhr.open("GET", url);
xhr.send();
}
}
var Game = pc.createScript('game');
Game.attributes.add('display', {
type: 'asset',
assetType: 'html'
});
Game.attributes.add('style', {
type: 'asset',
assetType: 'css'
});
// Create a script attribute to enable the drag and drop of a JSON asset containing character data
Game.attributes.add('characterData', {
type: 'asset',
assetType: 'json'
});
// initialize code called once per entity
Game.prototype.initialize = function() {
this.initDisplay();
var el;
// Get JSON data from a project asset
var characterData = this.characterData.resource;
// Parse JSON data
var names = this.parseCharacterData(characterData);
// display character names
el = document.querySelector("#character-name");
el.textContent = names.join(", ");
// display JSON data from asset
el = document.querySelector("#asset-json");
el.textContent = JSON.stringify(characterData, null, 4);
// load JSON from a remote server
this.loadJsonFromRemote("https://api.github.com/", function (data) {
// display JSON data from remote server
el = document.querySelector("#xhr-json");
el.textContent = JSON.stringify(data, null, 4);
});
};
Game.prototype.initDisplay = function () {
var el = pc.createStyle(this.style.resource);
document.head.appendChild(el);
var div = document.createElement("div");
div.setAttribute("id", "container");
div.innerHTML = this.display.resource;
document.body.appendChild(div);
};
Game.prototype.parseCharacterData = function (data) {
var names = [];
// Read the character data from the JSON asset and return a list of names
var characters = data.characters;
for (var i = 0; i < characters.length; i++) {
var character = characters[i];
names.push(character.firstName + ' ' + character.lastName);
}
return names;
};
Game.prototype.loadJsonFromRemote = function (url, callback) {
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function () {
callback(JSON.parse(this.response));
});
xhr.open("GET", url);
xhr.send();
};
亲自尝试此项目。