Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
199 views
in Technique[技术] by (71.8m points)

html - Table Not Rendering Properly with Async | PHP | API | LARAVEL

I have this async code , but when i try to render inside a table , the table become a mess (image) but after a page refresh the table is perfctly fine and i dont know why , how can i fix this problem ?

and if is possible to have a better async code , i know i need to async the $api->getMatchTimeline($match->gameId); but i don't know how can i do it.

   

   <table class="table table table-bordered" style="width:100%">
    <tr>
     <thead>
       <th>Items</th>
      </thead>
    </tr>
  
<tbody>

  <?php
$onSuccess = function (ObjectsMatchDto $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>
   
   

enter image description here

render outside the table

enter image description here

question from:https://stackoverflow.com/questions/65661393/table-not-rendering-properly-with-async-php-api-laravel

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem isn't to do with your "async" PHP code, but because your <table> markup is incorrect.

HTML's <table> element has two different forms. The first is the "implicit <tbody> form, like this:

<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 ObjectsMatchDto $match;
    public Array $items;
}

$allMatches = Array(); # Array of `MatchAndItems`.

$onFailure = function ($ex) {
    echo $ex;
};

$gotMatch = function (ObjectsMatchDto $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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...