問題描述
我想確保我在 Laravel 5 中正確使用了模型事件偵聽器,并且我沒有搞砸任何事情(偵聽器與處理程序?).我的解決方案工作正常,但我不知道我是否按照 Laravel 5 的概念和約定開發.
I would like to make sure that I correctly used model events listeners in Laravel 5 and I didn't messed up nothing (listener vs handler?). My solution works fine, but I wonder if I developed according to concept and convention of Laravel 5.
目標:保存模型時,始終將 $issue->status_id 設置為某個值.
Goal: Always set $issue->status_id on some value when model is saving.
在 appProvidersEventServiceProvider.php 中
In appProvidersEventServiceProvider.php
<?php namespace AppProviders;
...
class EventServiceProvider extends ServiceProvider {
...
public function boot(DispatcherContract $events)
{
parent::boot($events);
Issue::saving('AppHandlersEventsSetIssueStatus');
}
}
在 appHandlersEventsSetIssueStatus.php 中
In appHandlersEventsSetIssueStatus.php
<?php namespace AppHandlersEvents;
...
class SetIssueStatus {
...
public function handle(Issue $issue)
{
if (something)
{
$issueStatus = IssueStatus::where(somethingElse)->firstOrFail();
}
else
{
$issueStatus = IssueStatus::where(somethingAnother)->firstOrFail();
}
// issue_status() is One-to-One relations with IssueType (belongsTo)
$issue->issue_status()->associate($issueStatus);
}
}
感謝您的寶貴時間.
推薦答案
正如您所說,您有一個有效的版本并且它是有效的,現在由您來確定它是否適合您.
As you said you have a working version and it's a valid one, now that's up to you to figure out if it's ok for you.
澄清一下,我并不是說這些是更好的解決方案,它們只是一種有效的不同方式.
Just to clarify I'm not saying that these are better solutions, they are just a valid different way.
由于您所做的是特定于 Issue 模型的,或者至少它似乎不是一個通用事件,因此您可以直接在您的模型上進行設置
Since what you are doing is specific to the Issue model or at least it doesn't seem to be a generic event, you could set it up on your model directly
<?php namespace App;
use IlluminateDatabaseEloquentModel;
use IssueStatus;
class Issue extends Model {
protected static function boot()
{
parent::boot();
static::saving(function($issue){
if (something)
{
$issueStatus = IssueStatus::where(somethingElse)->firstOrFail();
}
else
{
$issueStatus = IssueStatus::where(somethingAnother)->firstOrFail();
}
// issue_status() is One-to-One relations with IssueType (belongsTo)
$issue->issue_status()->associate($issueStatus);
});
}
}
但如果您的事件確實是一個通用事件,并且您想在多個模型中使用它,則可以實現相同的目的.您只需要從模型中提取代碼并使用特征(就像軟刪除一樣)
but if your event is indeed a generic one and you want to use it across multiple Models, you could achieve the same thing. You just need to extract the code from the model and use traits (like you do with soft deletes)
首先,我們創建我們的 trait(在本例中,我們在應用程序的根目錄上創建)并從模型中提取我之前編寫的代碼:
First we create our trait(in this case we created on the root of our App) and extract the code, I wrote before, from the model:
<?php namespace App
use IssueStatus;
trait IssueStatusSetter
{
protected static function boot()
{
parent::boot();
static::saving(function($model){
if (something)
{
$issueStatus = IssueStatus::where(somethingElse)->firstOrFail();
}
else
{
$issueStatus = IssueStatus::where(somethingAnother)->firstOrFail();
}
// issue_status() is One-to-One relations with IssueType (belongsTo)
$model->issue_status()->associate($issueStatus);
});
}
}
現在在你想使用它的模型上,你只需導入特征并聲明它的使用:
Now on the models where you want to use it, you just import the trait and declare it's use:
<?php namespace App;
use IlluminateDatabaseEloquentModel;
use IssueStatusSetter;
class Issue extends Model {
use IssueStatusSetter;
}
現在我向您展示的最后一個選項是一個通用選項,您可以將其應用于每個模型,只需聲明它在模型頂部使用即可.
Now this last option I showed you it's a generic option you have that you could apply to every Model by just declaring it's use on the top of your model.
這篇關于在 Laravel 5 中使用模型事件監聽器的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!