タイムラインを表示したいのですが、ページにアクセスしたらまずbladeで初めデータを表示し、一番下まで遷移したら非同期で次のデータを取得・表示したいです。ですが、非同期で取得したデータはそれぞれ異なるデータのはずなのに全て同じ内容が表示されてしまいます。
該当のソースコード
sidebar.blade.php
1 <div id="timelineContainer"> 2 @if ($comments->count()) 3 @foreach ($comments as $comment) 4 <div class="streamTile"> 5 <div> 6 <a href="{{ route('articles.show', [$comment->article, 'id' => $comment->id]) }}"></a> 7 <div class="userInfo"> 8 <a href="{{ route('users.show', $comment->user) }}"> 9 <div class="userIcon"> 10 <img src="{{ \Storage::url($comment->user->icon ?? 'icon/initial.jpeg') }}" class="icon"> 11 </div> 12 <div> 13 <div class="userName _ellipsised"> 14 {{ $comment->user->name ?? '名前' }} 15 </div> 16 <div class="userID">{{ '@' . $comment->user->userID }}</div> 17 </div> 18 </a> 19 <div class="commentDate">{{ $comment->updated_at->diffForHumans() }}</div> 20 </div> 21 <div class="commentArea"> 22 <div class="comment _ellipsised"> 23 {!! mb_ereg_replace('(https?://[-_.!~*\'()a-zA-Z0-9;/?:@&=+$,%#]+)', '<a href="\1" target="_blank" rel="noopener noreferrer" class="linkedText">\1</a>', nl2br(e($comment->body))) !!} 24 </div> 25 </div> 26 <div class="titleArea"> 27 <div class="title _ellipsised">{{ $comment->article->title }}</div> 28 </div> 29 </div> 30 </div> 31 <div class="tileSeparator"></div> 32 @endforeach 33 @endif 34 </div>
index.blade.php
1 <script> 2 const timelineContainer = Vue.createApp({ 3 data: () => ({ 4 itemLoading: false, 5 load: true, 6 page: 0, 7 user: null, 8 article: null, 9 }), 10 11 mounted() { 12 gid('timelineContainer').onscroll = (e) => { 13 if (e.target.scrollTop + e.target.clientHeight >= e.target.scrollHeight) this.AjaxAddContent() 14 }; 15 }, 16 17 methods: { 18 async AjaxAddContent() { 19 if (!this.itemLoading) { //読み込み中は読み込めないようにする 20 this.itemLoading = true 21 // 追加コンテンツ 22 let AddContent = ""; 23 fetch('/comments/getComment', { 24 method: 'POST', 25 body: new URLSearchParams({ 26 count: this.page 27 }), 28 headers: { 29 'X-CSRF-TOKEN': gid("jsHandOvers").dataset.csrf 30 }, 31 }).then(res => { 32 return res.json(); 33 }).then(data => { 34 data.comments.forEach(streamTile => { 35 this.getCommentUser(streamTile.user_id) 36 this.getCommentArticle(streamTile.article_id) 37 let user = this.user 38 let article = this.article 39 AddContent += 40 `<div class="streamTile"><div><a href="/articles/${streamTile.article_id}?id=${streamTile.id}"></a><div class="userInfo"><a href="/users/${user.userID}"><div class="userIcon"><img src="/storage/${user.icon ?? 'icon/initial.jpeg'}" class="icon"></div><div><div class="userName _ellipsised"> 41 ${user.name ?? '名もなき電子の藻屑'}</div><div class="userID">@ 42 ${user.userID}</div></div></a><div class="commentDate"> 43 ${streamTile.updated_at}</div></div><div class="commentArea"><div class="comment _ellipsised"> 44 ${streamTile.body ?? ''}</div></div><div class="titleArea"><div class="title _ellipsised"> 45 ${article.title}</div></div></div></div><div class="tileSeparator"></div>`; 46 ↓forEachを一回回すごと個別の表示データをnullにしてるはずなのに同じ内容が表示されてしまう 47 this.user = null 48 this.article = null 49 }); 50 $('#timelineContainer').append(AddContent); 51 this.page += data.comments.length 52 }).catch(err => { 53 console.log(err.response) 54 this.itemLoading = false 55 }).finally(hoge => { 56 this.itemLoading = false 57 }) 58 } 59 }, 60 async getCommentUser(user_id) { 61 await fetch(`/users/${user_id}`, { 62 method: 'POST', 63 headers: { 64 'X-CSRF-TOKEN': gid("jsHandOvers").dataset.csrf 65 }, 66 }).then(res => { 67 return res.json(); 68 }).then(data => { 69 this.user = data.user 70 }).catch(err => { 71 console.log(err.response) 72 }) 73 }, 74 async getCommentArticle(article_id) { 75 await fetch(`/articles/${article_id}`, { 76 method: 'POST', 77 headers: { 78 'X-CSRF-TOKEN': gid("jsHandOvers").dataset.csrf 79 }, 80 }).then(res => { 81 return res.json(); 82 }).then(data => { 83 this.article = data.article 84 }).catch(err => { 85 console.log(err.response) 86 }) 87 }, 88 } 89 }).mount("#timelineContainer"); 90 </script>
web.php
1Route::post('/comments/getComment', [CommentController::class, 'getComment']); 2Route::post('/users/{user}', [UserController::class, 'getCommentUser'])->where('user', '[0-9]+'); 3Route::post('/articles/{article}', [ArticleController::class, 'getCommentArticle'])->where('article', '[0-9]+');
UserController.php
1 public function getCommentUser(User $user) 2 { 3 $json = ['user' => $user]; 4 header("Content-type: application/json; charset=UTF-8"); 5 echo json_encode($json); 6 }
ArticleController.php
1 public function getCommentArticle(Article $article) 2 { 3 $json = ['article' => $article]; 4 header("Content-type: application/json; charset=UTF-8"); 5 echo json_encode($json); 6 }
CommentController.php
1 public function getCommentArticle(Article $article) 2 { 3 $json = ['article' => $article]; 4 header("Content-type: application/json; charset=UTF-8"); 5 echo json_encode($json); 6 }
試したこと
下記リンクを参考にしたが解決できませんでした
https://teratail.com/questions/291159
補足情報(FW/ツールのバージョンなど)
PHP 8.1.1
Laravel 8.79.0
回答1件
あなたの回答
tips
プレビュー