Typescript can';web组件类中的t set属性
我想创建一个从php服务器获取json数据的组件,然后将数据放入Typescript can';web组件类中的t set属性,typescript,web-component,Typescript,Web Component,我想创建一个从php服务器获取json数据的组件,然后将数据放入ResultGrid类属性中,名为jsonProps我定义了属性,typescript没有抱怨,但是,当我在浏览器中运行代码时,浏览器无法识别我设置的属性,下面是代码 我还尝试在typescript中使用setter,但它不起作用(我发布的typescript代码没有使用它,而是以前的版本) HTML文件 <!DOCTYPE html> <html lang="en"> <head&
ResultGrid
类属性中,名为jsonProps
我定义了属性,typescript没有抱怨,但是,当我在浏览器中运行代码时,浏览器无法识别我设置的属性,下面是代码
我还尝试在typescript中使用setter,但它不起作用(我发布的typescript代码没有使用它,而是以前的版本)
HTML文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File</title>
</head>
<body>
</body>
<script src="ract.js"></script>
</html>
错误消息是:
未捕获类型错误:this.jsonProps未定义
您正在获取数据异步
let SHOW: boolean = false;
class InputText extends HTMLElement {
constructor() {
super();
let template = document.createElement("template");
template.innerHTML = this.render();
this.attachShadow({mode: "open"});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
render(): string {
return(`
<div>
1. Nama:
<input type="text" name="nama">
</div>
<div>
2. NRP:
<input type="text" name="nrp">
</div>
<div>
3. Kelas:
<input type="text" name="kelas">
</div>
<div>
4. Jenis kelamin:
<input type="radio" name="kelamin" value="pria">
Pria
<input type="radio" name="kelamin" value="wanita">
Wanita
</div>
<div>
5. Agama:
<select name="agama">
<option value="islam">Islam</option>
<option value="kristen">Kristen</option>
<option value="katolik">Katolik</option>
<option value="hindu">Hindu</option>
<option value="budha">Budha</option>
<option value="konghucu">Konghucu</option>
</select>
</div>
<div>
6. Tempat / Tanggal lahir:
<input type="text" name="tempat">
<input type="text" name="tgl">
</div>
<div>
7. Alamat
</div>
<textarea name="alamat" cols="30" rows="10"></textarea>
<div>
8. Riwayat pendidikan:
<ul type="a">
<li>
SD:
<input type="text" name="sd">
</li>
<li>
SMP:
<input type="text" name="smp">
</li>
<li>
SMA:
<input type="text" name="sma">
</li>
</ul>
</div>
<div>
9. Email
<input type="email" name="email">
</div>
<div>
10. Homepage
<input type="url" name="homepage">
</div>
<div>
11. Hobby
</div>
<textarea name="hobby" cols="30" rows="10"></textarea>
<div>
12. interest:
<input type="checkbox" name="interest1" value="komputer">
komputer
<input type="checkbox" name="interest2" value="sport">
sport
<input type="checkbox" name="interest3" value="travelling">
travelling
<input type="checkbox" name="interest4" value="writing">
writing
<input type="checkbox" name="interest5" value="reading">
reading
</div>
<div>
<button onclick="router()">Simpan</button>
<button type="reset">Reset</button>
</div>
`);
}
}
class ResultGrid extends HTMLElement {
jsonProps: Record<string, string | string[]>;
constructor() {
super();
this.jsonProps; // this property is undefined in the browser
}
connectedCallback() {
this.getData();
let template = document.createElement("template");
template.innerHTML = this.render();
this.attachShadow({mode: "open"});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
async getData() {
let url = // read.php url;
try {
let res = await fetch(url, {
headers: {
'Accept': 'application/json;text/plain'
}
});
if(res.status !== 200) {
throw new Error(await res.text());
} else {
this.jsonProps = await res.json(); // setting property here
}
} catch(e) {
console.error(e.message);
}
}
render() {
return (`
<style>
#grid {
display: grid;
width: 40vw;
grid-template-columns: 1fr 1fr;
}
</style>
<div id="grid">
<div>Nama</div>
<div>${this.jsonProps.nama}</div>
<div>Nrp</div>
<div>${this.jsonProps.nrp}</div>
<div>Kelas</div>
<div>${this.jsonProps.kelas}</div>
<div>Jenis Kelamin</div>
<div>${this.jsonProps.kelamin}</div>
<div>Agama</div>
<div>${this.jsonProps.agama}</div>
<div>Tempat</div>
<div>${this.jsonProps.tempat}</div>
<div>Tanggal lahir</div>
<div>${this.jsonProps.tgl}</div>
<div>Alamat</div>
<div>${this.jsonProps.alamat}</div>
<div>SD</div>
<div>${this.jsonProps.sd}</div>
<div>SMP</div>
<div>${this.jsonProps.smp}</div>
<div>SMA</div>
<div>${this.jsonProps.sma}</div>
<div>Email</div>
<div>${this.jsonProps.email}</div>
<div>Homepage</div>
<div>${this.jsonProps.homepage}</div>
<div>Hobby</div>
<div>${this.jsonProps.hobby}</div>
<div>Interest</div>
<div>${(this.jsonProps.interests as string[]).map((itr: string) => itr)}</div>
<button onclick="router()">return</button>
</div>
`);
}
}
(function init() {
customElements.define("input-text", InputText);
customElements.define("result-grid", ResultGrid);
let input = document.createElement("input-text");
document.body.appendChild(input);
})()
function router() {
if(SHOW === false) {
(async () => {
let inputShadow = document.querySelector("input-text").shadowRoot;
const url: string = // savetofile.php url;
let intagr: string[] = [];
(function() {
(inputShadow.querySelector('input[name="interest1"]') as HTMLInputElement).checked &&
intagr.push((inputShadow.querySelector('input[name="interest1"]') as HTMLInputElement).value);
(inputShadow.querySelector('input[name="interest2"]') as HTMLInputElement).checked &&
intagr.push((inputShadow.querySelector('input[name="interest2"]') as HTMLInputElement).value);
(inputShadow.querySelector('input[name="interest3"]') as HTMLInputElement).checked &&
intagr.push((inputShadow.querySelector('input[name="interest3"]') as HTMLInputElement).value);
(inputShadow.querySelector('input[name="interest4"]') as HTMLInputElement).checked &&
intagr.push((inputShadow.querySelector('input[name="interest4"]') as HTMLInputElement).value);
(inputShadow.querySelector('input[name="interest5"]') as HTMLInputElement).checked &&
intagr.push((inputShadow.querySelector('input[name="interest5"]') as HTMLInputElement).value);
})();
let send: Record<string, string | string[]> = {
nama: (inputShadow.querySelector('input[name="nama"]') as HTMLInputElement).value,
nrp: (inputShadow.querySelector('input[name="nrp"]') as HTMLInputElement).value,
kelas: (inputShadow.querySelector('input[name="kelas"]') as HTMLInputElement).value,
kelamin: (inputShadow.querySelector('input[name="kelamin"]') as HTMLInputElement).value,
agama: (inputShadow.querySelector("select") as HTMLSelectElement).value,
tempat: (inputShadow.querySelector('input[name="tempat"]') as HTMLInputElement).value,
tgl: (inputShadow.querySelector('input[name="tgl"]') as HTMLInputElement).value,
alamat: (inputShadow.querySelector('textarea[name="alamat"]') as HTMLTextAreaElement).value,
sd: (inputShadow.querySelector('input[name="sd"]') as HTMLInputElement).value,
smp: (inputShadow.querySelector('input[name="smp"]') as HTMLInputElement).value,
sma: (inputShadow.querySelector('input[name="sma"]') as HTMLInputElement).value,
email: (inputShadow.querySelector('input[name="email"]') as HTMLInputElement).value,
homepage: (inputShadow.querySelector('input[name="homepage"]') as HTMLInputElement).value,
hobby: (inputShadow.querySelector('textarea[name="hobby"]') as HTMLTextAreaElement).value,
interests: intagr
}
try {
let res = await fetch(url, {
method: 'POST',
body: JSON.stringify(send),
headers: {
'Content-type': "application/json",
'Accept': "text/plain"
}
});
if(res.status !== 200) {
let text = await res.text();
throw new Error(text);
}
} catch (error) {
alert(error.message);
}
})();
document.querySelector("input-text").remove();
let resultPage = document.createElement("result-grid");
document.body.appendChild(resultPage);
SHOW = true;
} else {
document.querySelector("result-grid").remove();
let inputPage = document.createElement("input-text");
document.body.appendChild(inputPage);
SHOW = false;
}
}
- 因此,
是this.jsonProps
,直到未定义的
函数收到它:getData()
- 移动
调用render()
- (而且不需要昂贵的
来创建HTML)
正如@danny-365csi-engelman所建议的 读过之后呢 我将整个异步函数移到了connectedCallback()中 并更新渲染方法
render(jsonProps: Record<string, string | string[]>) {
return (`
<style>
#grid {
display: grid;
width: 40vw;
grid-template-columns: 1fr 1fr;
}
</style>
<div id="grid">
<div>Nama</div>
<div>${jsonProps.nama}</div>
<div>Nrp</div>
<div>${jsonProps.nrp}</div>
<div>Kelas</div>
<div>${jsonProps.kelas}</div>
<div>Jenis Kelamin</div>
<div>${jsonProps.kelamin}</div>
<div>Agama</div>
<div>${jsonProps.agama}</div>
<div>Tempat</div>
<div>${jsonProps.tempat}</div>
<div>Tanggal lahir</div>
<div>${jsonProps.tgl}</div>
<div>Alamat</div>
<div>${jsonProps.alamat}</div>
<div>SD</div>
<div>${jsonProps.sd}</div>
<div>SMP</div>
<div>${jsonProps.smp}</div>
<div>SMA</div>
<div>${jsonProps.sma}</div>
<div>Email</div>
<div>${jsonProps.email}</div>
<div>Homepage</div>
<div>${jsonProps.homepage}</div>
<div>Hobby</div>
<div>${jsonProps.hobby}</div>
<div>Interest</div>
<div>${(jsonProps.interests as string[]).map((itr: string) => itr)}</div>
<button onclick="router()">return</button>
</div>
`);
}
render(jsonProps:Record){
返回(`
#网格{
显示:网格;
宽度:40vw;
网格模板柱:1fr 1fr;
}
纳米
${jsonProps.nama}
Nrp
${jsonProps.nrp}
卡拉斯
${jsonProps.kelas}
杰尼斯·克拉明
${jsonProps.kelamin}
阿加玛
${jsonProps.agama}
坦帕
${jsonProps.tempat}
唐加拉希尔
${jsonProps.tgl}
阿拉马特
${jsonProps.alamat}
SD
${jsonProps.sd}
开关电源
${jsonProps.smp}
SMA
${jsonProps.sma}
电子邮件
${jsonProps.email}
主页
${jsonProps.homepage}
爱好
${jsonProps.hobby}
兴趣
${(jsonProps.interests as string[]).map((itr:string)=>itr)}
返回
`);
}
@danny-365csi-engelman我将渲染移到了异步部分中,可以说它现在可以工作了。您仍然在使用臃肿的模板
仅用于插入HTML。这将完成:This.attachShadow({mode:“open”}).innerHTML=This.render(wait rs.json())代码>
<?php
try {
$filename = './data.json';
$json_file = fopen($filename, 'r');
if(!$json_file) {
throw new Exception("error opening file", 1);
} else {
header("Content-type: application/json");
$read_file = fread($json_file, filesize($filename));
echo json_encode(json_decode($read_file));
}
fclose();
} catch (Exception $th) {
header("Content-type: text/plain");
http_response_code(500);
echo $th->getMessage();
}
?>
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"lib": ["ESNext", "DOM"],
"noImplicitAny": true,
"preserveConstEnums": true,
"outDir": "./",
"sourceMap": true
},
"include": ["ract.ts"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
class ResultGrid extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.getData();
}
async getData() {
let url = // read.php url;
try {
let res = await fetch(url, {headers:'Accept': 'application/json;text/plain'}});
if(res.status !== 200) {
throw new Error(await res.text());
} else {
this.jsonProps = await res.json(); // setting property here
// !! NOW .render() can access this.jsonProps
this.attachShadow({mode:"open"}).innerHTML = this.render();
}
} catch(e) {
console.error(e.message);
}
}
class ResultGrid extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
(async () => {
let url = // read.php url
try {
let res = await fetch(url, {
headers: {
'Accept': 'application/json;text/plain'
}
});
if(res.status !== 200) {
throw new Error(await res.text());
} else {
let template = document.createElement("template");
template.innerHTML = this.render(await res.json());
this.attachShadow({mode: "open"});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
} catch(e) {
console.error(e.message);
}
})();
}
render(jsonProps: Record<string, string | string[]>) {
return (`
<style>
#grid {
display: grid;
width: 40vw;
grid-template-columns: 1fr 1fr;
}
</style>
<div id="grid">
<div>Nama</div>
<div>${jsonProps.nama}</div>
<div>Nrp</div>
<div>${jsonProps.nrp}</div>
<div>Kelas</div>
<div>${jsonProps.kelas}</div>
<div>Jenis Kelamin</div>
<div>${jsonProps.kelamin}</div>
<div>Agama</div>
<div>${jsonProps.agama}</div>
<div>Tempat</div>
<div>${jsonProps.tempat}</div>
<div>Tanggal lahir</div>
<div>${jsonProps.tgl}</div>
<div>Alamat</div>
<div>${jsonProps.alamat}</div>
<div>SD</div>
<div>${jsonProps.sd}</div>
<div>SMP</div>
<div>${jsonProps.smp}</div>
<div>SMA</div>
<div>${jsonProps.sma}</div>
<div>Email</div>
<div>${jsonProps.email}</div>
<div>Homepage</div>
<div>${jsonProps.homepage}</div>
<div>Hobby</div>
<div>${jsonProps.hobby}</div>
<div>Interest</div>
<div>${(jsonProps.interests as string[]).map((itr: string) => itr)}</div>
<button onclick="router()">return</button>
</div>
`);
}