私はこの非同期コードを持っていますが、テーブル内でレンダリングしようとすると、テーブルは混乱(画像)になりますが、ページの更新後、テーブルは完全に正常であり、理由がわかりません、どうすればこの問題を修正できますか?
そして、より良い非同期コードを使用できる場合は、非同期にする必要$api->getMatchTimeline($match->gameId);
があることはわかっていますが、どうすればよいかわかりません。
<table class="table table table-bordered" style="width:100%">
<tr>
<thead>
<th>Items</th>
</thead>
</tr>
<tbody>
<?php
$onSuccess = function (Objects\MatchDto $match) use (&$api, $champ) {
echo "<tr>";
echo "<td>";
foreach ($match->participants as $partId) {
if ($partId->championId == $champ) {
$participant_id = $partId->stats->participantId;
$pp = $api->getMatchTimeline($match->gameId);
foreach ($pp->frames as $p) {
foreach ($p->events as $t) {
if ($t->type == "ITEM_PURCHASED" and $t->participantId == $participant_id) {
$item_id = $t->itemId;
$d = $api->getStaticItem($item_id);
$depth = $d->depth;
if (($depth == 3 or $depth == 2)) {
echo "<a href = https://lolprofile.net/match/kr/$match->gameId#Match%20History >";
echo "<img src =" . DataDragonAPI::getItemIconUrl($item_id) . " />" . '</a>';
}
}
}
}
}
}
echo "</td>";
echo "</tr>";
};
$onFailure = function ($ex) {
echo $ex;
};
foreach ($database as $game) {
$api->nextAsync($onSuccess);
$match = $api->getMatch($game->match_ids);
}
$api->commitAsync();
?>
</tbody>
</table>
テーブルの外にレンダリング
問題は「非同期」PHPコードに関係しているのではなく、<table>
マークアップが正しくないためです。
HTMLの<table>
要素には2つの異なる形式があります。1つ目は、「次の<tbody>
ような暗黙の形式です。
<table>
<tr>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
</tr>
</table>
The other has an explicit <tbody>
element, which can also optionally have a <thead>
and <tfoot>
(you can also have multiple <tbody>
but only a single <thead>
. You can use a <thead>
and <tfoot>
with an implicit <tbody>
but this is not recommended - I recommend everyone use the explicit syntax, like so:
<table>
<tbody>
<tr>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
</tr>
</tbody>
</table>
Note that the actual DOM representation of both tables is the same: in the DOM a <table>
never has <tr>
as immediate children.
Secondarily, you can also make your code a LOT easier to read and follow if you separate your application logic from your rendering logic by doing all of your API calls and whatnot at the start of your PHP script and populate a "view model" object and then the rendering logic is greatly simplfied, like so:
<?php
// This PHP block should be before *any* HTML is written:
class MatchAndItems {
public Objects\MatchDto $match;
public Array $items;
}
$allMatches = Array(); # Array of `MatchAndItems`.
$onFailure = function ($ex) {
echo $ex;
};
$gotMatch = function (Objects\MatchDto $match) use (&$api, $champ, $allMatches) {
$e = new MatchAndItems();
$e->match = $match;
$e->items = array();
foreach ($match->participants as $partId) {
if ($partId->championId == $champ) {
$participant_id = $partId->stats->participantId;
$pp = $api->getMatchTimeline($match->gameId);
foreach ($pp->frames as $p) {
foreach ($p->events as $t) {
if ($t->type == "ITEM_PURCHASED" and $t->participantId == $participant_id) {
$item_id = $t->itemId;
$d = $api->getStaticItem($item_id);
array_push( $e->items, $d );
}
}
}
}
}
array_push( $allMatches, $e );
};
# Set-up web-service HTTP request batches:
foreach( $database as $game ) {
$api->nextAsync( $gotMatch )->getMatch( $game->match_ids );
}
# Invoke the batch:
$api->commitAsync();
# The below code uses https://www.php.net/manual/en/control-structures.alternative-syntax.php
?>
<!-- etc -->
<table class="table table table-bordered" style="width: 100%">
<thead>
<tr>
<th>Items</th>
</tr>
</thead>
<tbody>
<?php foreach( $allMatches as $match ): ?>
<tr>
<td>
<?php
foreach( $match->items as $item ):
if( $item->depth == 2 or $item->depth == 3 ):
echo "<a href = https://lolprofile.net/match/kr/$match->gameId#Match%20History >";
echo "<img src =" . DataDragonAPI::getItemIconUrl($item_id) . " />" . '</a>';
endif;
endforeach;
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加