【发布时间】:2021-08-01 14:25:02
【问题描述】:
我正在使用普通(普通)JavaScript 以 HTML 表格的形式显示 JSON。
我将从 JSON 动态创建的行附加到表的主体:
class CountriesList {
constructor() {
this.apiURL =
"https://gist.githubusercontent.com/Goles/3196253/raw/9ca4e7e62ea5ad935bb3580dc0a07d9df033b451/CountryCodes.json";
this.countries = [];
this.searchBox = document.querySelector("#searchBox");
this.stringToMatch = "";
this.tableRows = "";
}
// Render rows
renderRows = (arr, container) => {
let el = document.querySelector(container);
el.innerHTML = "";
el.innerHTML += arr
.map(function(item) {
return `<tr>
<td>${item.name}</td>
<td class="text-right">${item.code}</td>
<td class="text-right">
<button data-code="${item.code}" class="btn btn-sm btn-danger" onclick="this.deleteRow()">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</td>
</tr>`;
})
.join("");
};
// Get Items
getFilteredCountries = async() => {
const response = await fetch(this.apiURL);
this.countries = await response.json();
// If there is a search string, filter results
this.stringToMatch = this.searchBox.value;
if (this.stringToMatch.length > 0) {
this.countries = this.countries.filter((country) => {
return (
country.name.toLowerCase().includes(this.stringToMatch.toLowerCase()) ||
country.code.includes(this.stringToMatch.toUpperCase())
);
});
this.renderRows(this.countries, "#countries_table tbody");
}
};
deleteRow() {
let deleteBtns = document.querySelectorAll("#countries_table tr button");
console.log(event.target.dataset.code);
this.countries = this.countries.filter(() => item.code != event.target.dataset.code);
this.renderRows(this.countries, "#countries_table tbody");
};
hideLoader = async() => {
let loader = document.querySelector(".loader");
const action = this.countries.length > 0 ? "add" : "remove";
loader.classList[action]("d-none");
};
init = async() => {
await this.getFilteredCountries();
await this.hideLoader();
this.searchBox.addEventListener("keyup", this.getFilteredCountries);
this.renderRows(this.countries, "#countries_table tbody");
};
}
const countriesList = new CountriesList();
countriesList.init();
.loader {
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
opacity: .85;
border-radius: 50%;
width: 50px;
height: 50px;
position: absolute;
top: 50px;
left: 50%;
margin-left: -50px;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<div class="container-fluid">
<div class="card bg-light shadow-sm my-2">
<div class="card-header px-3 d-flex">
<h6 class="text-dark m-0 align-self-center">Countries of the World</h6>
</div>
<div class="card-body bg-white position-relative p-0">
<div class="search mx-2">
<input class="my-2 form-control" id="searchBox" type="text" placeholder="Search..." value="">
</div>
<table class="table mb-0" id="countries_table">
<thead>
<tr>
<th>Country</th>
<th class="text-right">Code</th>
<th class="text-right">Delete</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div class="loader"></div>
</div>
</div>
</div>
问题
在 renderRows 方法的模板文字中,我添加了一个删除按钮:
<button data-code="${item.code}" class="btn btn-sm btn-danger" onclick="this.deleteRow()">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
当我单击删除按钮时,我在浏览器中收到此错误:
Uncaught TypeError: this.deleteRow is not a function
我做错了什么?
【问题讨论】:
-
this在 html 属性中不是对象的实例 -
您不能在 HTML 中直接引用 this 删除 this 关键字,它应该可以正常工作
-
@AkshayBhat 它不在 HTML 中,而是在脚本中,其中每个方法 id 都以
this调用。 -
@RazvanZamfir 您在创建 HTML 时传递字符串,而不是函数本身,因此单击后,
this等于window而不是 CountryList。 -
@FilipKováč 我删除了
this关键字,但它仍然不起作用。 :(
标签: javascript es6-class