跳至内容

04. 显示 Chirps

在前面的步骤中,我们添加了创建 Chirps 的功能,现在我们准备显示它们!

检索 Chirps

首先,我们应该更新我们的 resources/views/chirps.blade.php 视图以显示 Chirps 列表。为此,我们可以使用一个新的 Livewire 组件

resources/views/chirps.blade.php
<x-app-layout>
<div class="max-w-2xl mx-auto p-4 sm:p-6 lg:p-8">
<livewire:chirps.create />
+
+ <livewire:chirps.list />
</div>
</x-app-layout>

然后,让我们创建一个新的 chirps.list Livewire 组件

php artisan make:volt chirps/list --class
php artisan make:volt chirps/list

这将在 resources/views/livewire/chirps/list.blade.php 中创建一个新的 Livewire 组件。让我们更新 Livewire 组件以显示我们的 Chirps 列表

resources/views/livewire/chirps/list.blade.php
<?php
 
+use App\Models\Chirp;
+use Illuminate\Database\Eloquent\Collection;
use Livewire\Volt\Component;
 
new class extends Component
{
+ public Collection $chirps;
+ 
+ public function mount(): void
+ {
+ $this->chirps = Chirp::with('user')
+ ->latest()
+ ->get();
+ }
}; ?>
 
-<div>
- //
+<div class="mt-6 bg-white shadow-sm rounded-lg divide-y">
+ @foreach ($chirps as $chirp)
+ <div class="p-6 flex space-x-2" wire:key="{{ $chirp->id }}">
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600 -scale-x-100" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
+ <path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
+ </svg>
+ <div class="flex-1">
+ <div class="flex justify-between items-center">
+ <div>
+ <span class="text-gray-800">{{ $chirp->user->name }}</span>
+ <small class="ml-2 text-sm text-gray-600">{{ $chirp->created_at->format('j M Y, g:i a') }}</small>
+ </div>
+ </div>
+ <p class="mt-4 text-lg text-gray-900">{{ $chirp->message }}</p>
+ </div>
+ </div>
+ @endforeach
</div>
resources/views/livewire/chirps/list.blade.php
<?php
 
+use App\Models\Chirp;
use function Livewire\Volt\{state};
 
+state(['chirps' => fn () => Chirp::with('user')->latest()->get()]);
 
?>
 
-<div>
- //
+<div class="mt-6 bg-white shadow-sm rounded-lg divide-y">
+ @foreach ($chirps as $chirp)
+ <div class="p-6 flex space-x-2" wire:key="{{ $chirp->id }}">
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600 -scale-x-100" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
+ <path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
+ </svg>
+ <div class="flex-1">
+ <div class="flex justify-between items-center">
+ <div>
+ <span class="text-gray-800">{{ $chirp->user->name }}</span>
+ <small class="ml-2 text-sm text-gray-600">{{ $chirp->created_at->format('j M Y, g:i a') }}</small>
+ </div>
+ </div>
+ <p class="mt-4 text-lg text-gray-900">{{ $chirp->message }}</p>
+ </div>
+ </div>
+ @endforeach
</div>

在这里,我们使用了 Eloquent 的 with 方法来 预加载 每个 Chirp 关联的用户。我们还使用了 latest 作用域来按逆时间顺序返回记录。

最后,每次创建新的 Chirp 时,都需要更新 Chirps 列表。我们可以使用 Livewire 事件 来实现。让我们在每次创建新的 Chirp 时分派一个事件

resources/views/livewire/chirps/create.blade.php
<?php
 ...
use Livewire\Attributes\Validate;
use Livewire\Volt\Component;
 
new class extends Component
{
#[Validate('required|string|max:255')]
public $message = '';
 
public function store(): void
{
$validated = $this->validate();
 
auth()->user()->chirps()->create($validated);
 
$this->message = '';
+ 
+ $this->dispatch('chirp-created');
}
}; ?>
 
<div> ...
<form wire:submit="store">
<textarea
wire:model="message"
placeholder="{{ __('What\'s on your mind?') }}"
class="block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm"
/>
<x-input-error :messages="$errors->get('message')" class="mt-2" />
<x-primary-button class="mt-4">{{ __('Chirp') }}</x-primary-button>
</form>
</div>
resources/views/livewire/chirps/create.blade.php
<?php
 ...
use function Livewire\Volt\{state};
use function Livewire\Volt\{rules, state};
 
state(['message' => '']);
 
rules(['message' => 'required|string|max:255']);
 
$store = function () {
$validated = $this->validate();
 
auth()->user()->chirps()->create($validated);
 
$this->message = '';
+ 
+ $this->dispatch('chirp-created');
};
 
?>
 
<div> ...
<form wire:submit="store">
<textarea
wire:model="message"
placeholder="{{ __('What\'s on your mind?') }}"
class="block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm"
/>
 
<x-input-error :messages="$errors->get('message')" class="mt-2" />
<x-primary-button class="mt-4">{{ __('Chirp') }}</x-primary-button>
</form>
</div>

现在,我们可以更新我们的 `chirps.list` 组件来监听 `chirp-created` 事件,并更新 Chirps 列表。

resources/views/livewire/chirps/list.blade.php
<?php
 
use App\Models\Chirp;
use Illuminate\Database\Eloquent\Collection;
+use Livewire\Attributes\On;
use Livewire\Volt\Component;
 
new class extends Component
{
public Collection $chirps;
 
public function mount(): void
{
- $this->chirps = Chirp::with('user')
- ->latest()
- ->get();
+ $this->getChirps();
}
+ 
+ #[On('chirp-created')]
+ public function getChirps(): void
+ {
+ $this->chirps = Chirp::with('user')
+ ->latest()
+ ->get();
+ }
}; ?>
 
<div class="mt-6 bg-white shadow-sm rounded-lg divide-y">
...
@foreach ($chirps as $chirp)
<div class="p-6 flex space-x-2" wire:key="{{ $chirp->id }}">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600 -scale-x-100" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg>
<div class="flex-1">
<div class="flex justify-between items-center">
<div>
<span class="text-gray-800">{{ $chirp->user->name }}</span>
<small class="ml-2 text-sm text-gray-600">{{ $chirp->created_at->format('j M Y, g:i a') }}</small>
</div>
</div>
<p class="mt-4 text-lg text-gray-900">{{ $chirp->message }}</p>
</div>
</div>
@endforeach
</div>
resources/views/livewire/chirps/list.blade.php
<?php
 
use App\Models\Chirp;
-use function Livewire\Volt\{state};
+use function Livewire\Volt\{on, state};
 
-state(['chirps' => Chirp::with('user')->latest()->get()]);
+$getChirps = fn () => $this->chirps = Chirp::with('user')->latest()->get();
+ 
+state(['chirps' => $getChirps]);
+ 
+on(['chirp-created' => $getChirps]);
 
?>
 
<div class="mt-6 bg-white shadow-sm rounded-lg divide-y">
...
@foreach ($chirps as $chirp)
<div class="p-6 flex space-x-2" wire:key="{{ $chirp->id }}">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600 -scale-x-100" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg>
<div class="flex-1">
<div class="flex justify-between items-center">
<div>
<span class="text-gray-800">{{ $chirp->user->name }}</span>
<small class="ml-2 text-sm text-gray-600">{{ $chirp->created_at->format('j M Y, g:i a') }}</small>
</div>
</div>
<p class="mt-4 text-lg text-gray-900">{{ $chirp->message }}</p>
</div>
</div>
@endforeach
</div>

将用户连接到 Chirps

我们已经指示 Laravel 返回 `user` 关系,以便我们可以显示 Chirp 作者的姓名。但是,Chirp 的 `user` 关系尚未定义。为了解决这个问题,让我们在 `Chirp` 模型中添加一个新的 "属于" 关系。

app/Models/Chirp.php
<?php
 ...
namespace App\Models;
 
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
class Chirp extends Model
{
 ...
use HasFactory;
 
protected $fillable = [
'message',
];
 
+ public function user(): BelongsTo
+ {
+ return $this->belongsTo(User::class);
+ }
}

这种关系是我们之前在 `User` 模型中创建的“一对多”关系的逆关系。

现在看看你的浏览器,看看你之前 Chirped 的消息!

Chirp listing

随意 Chirping 更多,甚至注册另一个帐户并开始对话!

继续允许编辑 Chirps...