英文:
How to display the search result from array of object in rxjs?
问题
我正在使用rxjs库,并使用简单的JavaScript来实现我的代码。我使用ajax来进行游戏的API请求,然后将所有数据映射到表格中。表格包括游戏的名称、发布日期和流派。现在我只需根据输入搜索显示行;基本上,用户将通过名称搜索游戏,只有该游戏的数据将显示在该行。如何使用Rxjs实现这样的功能?
我已经添加了代码片段。
注意:获取数据需要4-5秒。
<!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>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.0/rxjs.umd.min.js"
integrity="sha512-v0/YVjBcbjLN6scjmmJN+h86koeB7JhY4/2YeyA5l+rTdtKLv0VbDBNJ32rxJpsaW1QGMd1Z16lsLOSGI38Rbg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
<h1>Games</h1>
<input type="text" name="" id="search_game" placeholder="search games">
<p id="test"></p>
<table cellpadding="10">
<thead>
<tr>
<th style="text-align:left;" id="game_name">Name</th>
<th style="text-align:left;">Released</th>
<th style="text-align:left;">Genre</th>
</tr>
</thead>
<tbody id="table-content">
</tbody>
</table>
</body>
<script>
const { of, fromEvent, ajax: { ajax }, operators: { startWith, switchMap, map, debounce }, combineLatest } = rxjs;
const searchGame = document.getElementById('search_game');
const search = fromEvent(searchGame, 'input');
search.subscribe(e => console.log(e.target.value));
const games = ajax.getJSON('https://api.sampleapis.com/switch/games');
games.subscribe(gamesList => {
let tableContent = '';
gamesList.forEach(game => {
tableContent += '<tr>';
tableContent += '<td>' + game.name + '</td>';
tableContent += '<td>' + (!game.releaseDates.Japan + ' ' + '(Japan)' ? game.releaseDates.Europe + ' ' + '(Europe)' : game.releaseDates.Australia + ' ' + '(Australia)') + '</td>';
tableContent += '<td>' + game.genre + '</td>';
});
document.getElementById('table-content').innerHTML = tableContent;
console.log(gamesList);
});
var x = document.getElementById('game_name').value;
</script>
</html>
这段代码是使用Rxjs库进行游戏数据搜索和呈现的示例。当用户在输入框中输入游戏名称时,它会根据输入实时更新表格内容,只显示与搜索匹配的游戏数据。
英文:
So I am using rxjs library and implementing my code using simple javascript. So I used ajax to make an API request for games and then mapped all the data inside the table, the table has the name of the game, released date, and genre. Now I have to only show the row based on the input search; basically, the user will search the game by name and only the data of that respective game will be shown in that particular row. How can we achieve such functionality using Rxjs?
I have added the snippet of the code.<br>
Note: It takes 4-5 sec to fetch data.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-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>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.0/rxjs.umd.min.js"
integrity="sha512-v0/YVjBcbjLN6scjmmJN+h86koeB7JhY4/2YeyA5l+rTdtKLv0VbDBNJ32rxJpsaW1QGMd1Z16lsLOSGI38Rbg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>>
</head>
<body>
<h1>Games</h1>
<input type="text" name="" id="search_game" placeholder="search games">
<p id="test"></p>
<table cellpadding="10">
<thead>
<tr>
<th style="text-align:left;"id="game_name">Name</th>
<th style="text-align:left;">Released</th>
<th style="text-align:left;">Genre</th>
</tr>
<tbody id="table-content">
</tbody>
</thead>
</table>
</body>
<script>
const { of, fromEvent, ajax: { ajax }, operators: { startWith, switchMap, map, debounce }, combineLatest } = rxjs;
const searchGame = document.getElementById('search_game');
const search = fromEvent(searchGame, 'input');
search.subscribe(e=>console.log(e.target.value));
const games = ajax.getJSON('https://api.sampleapis.com/switch/games');
games.subscribe(gamesList => {
let tableContent = '';
gamesList.forEach(game => {
tableContent += `<tr>`;
tableContent += `<td>` + game.name + `</td>`
tableContent += `<td>` + (!game.releaseDates.Japan + ' ' + '(Japan)' ? game.releaseDates.Europe + ' ' + `(Europe)` : game.releaseDates.Australia + ' ' + `(Australia)`) + `</td>`
tableContent += `<td>` + game.genre + `</td>`
})
document.getElementById('table-content').innerHTML = tableContent
console.log(gamesList);
})
var x = document.getElementById('game_name').value;
</script>
</html>
<!-- end snippet -->
答案1
得分: 1
你需要将搜索映射到它的值,并且使其以某种方式开始,这样你就不需要先按键。
const search = fromEvent(searchGame, 'input').pipe(
map(e => e.target.value),
startWith('')
);
然后你可以在这两个可观察对象上使用 combine latest 来过滤只包含搜索字符串的游戏。
const { of, fromEvent, ajax: { ajax }, operators: { startWith, switchMap, map, debounce }, combineLatest } = rxjs;
const searchGame = document.getElementById('search_game');
const search = fromEvent(searchGame, 'input').pipe(
map(e => e.target.value),
startWith('')
);
const games = ajax.getJSON('https://api.sampleapis.com/switch/games');
combineLatest([games, search]).pipe(
map(([games, search]) => games.filter(game => game.name.indexOf(search) !== -1))
)
.subscribe(gamesList => {
let tableContent = '';
gamesList.forEach(game => {
tableContent += '<tr>';
tableContent += '<td>' + game.name + '</td>'
tableContent += '<td>' + (!game.releaseDates.Japan + ' ' + '(Japan)' ? game.releaseDates.Europe + ' ' + '(Europe)' : game.releaseDates.Australia + ' ' + '(Australia)') + '</td>'
tableContent += '<td>' + game.genre + '</td>'
})
document.getElementById('table-content').innerHTML = tableContent
});
英文:
You need to map the search to it's value and make it start with something so you don't need to press a key first.
const search = fromEvent(searchGame, 'input').pipe(
map(e => e.target.value),
startWith('')
);
then you can use combine latest on the two observables to filter the games to just the ones where the name contains the search string.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const { of, fromEvent, ajax: { ajax }, operators: { startWith, switchMap, map, debounce }, combineLatest } = rxjs;
const searchGame = document.getElementById('search_game');
const search = fromEvent(searchGame, 'input').pipe(
map(e => e.target.value),
startWith('') // Otherwise you wont get any results until you press a key
);
const games = ajax.getJSON('https://api.sampleapis.com/switch/games');
combineLatest([games, search]).pipe(
map(([games, search]) => games.filter(game => game.name.indexOf(search) !== -1))
)
.subscribe(gamesList => {
let tableContent = '';
gamesList.forEach(game => {
tableContent += `<tr>`;
tableContent += `<td>` + game.name + `</td>`
tableContent += `<td>` + (!game.releaseDates.Japan + ' ' + '(Japan)' ? game.releaseDates.Europe + ' ' + `(Europe)` : game.releaseDates.Australia + ' ' + `(Australia)`) + `</td>`
tableContent += `<td>` + game.genre + `</td>`
})
document.getElementById('table-content').innerHTML = tableContent
});
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.0/rxjs.umd.min.js"
integrity="sha512-v0/YVjBcbjLN6scjmmJN+h86koeB7JhY4/2YeyA5l+rTdtKLv0VbDBNJ32rxJpsaW1QGMd1Z16lsLOSGI38Rbg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<h1>Games</h1>
<input type="text" name="" id="search_game" placeholder="search games">
<p id="test"></p>
<table cellpadding="10">
<thead>
<tr>
<th style="text-align:left;"id="game_name">Name</th>
<th style="text-align:left;">Released</th>
<th style="text-align:left;">Genre</th>
</tr>
<tbody id="table-content">
</tbody>
</thead>
</table>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论