2015-09-14 60 views
2

編輯:這個問題更多的是關於如何在一個函數內創建一個契約。我如何創建方法來完成簡單的事情並在對象之間有需求?我是否:Laravel/MVC:在哪裏返回部分響應數據

1)在start()方法中添加檢查和異常以創建合約,並將暫停循環置於不同的調用中? (下面是對數據源的一個小的重複調用。)

2)添加一個事件偵聽器,以便每當定時器開始創建合約時? (我不確定我是否可以用這種方法返回數據,我也不確定在啓動新計時器之前,我可以保證事件會成功完成,在這種情況下可能無關緊要。 )

3)只需從啓動函數返回id並處理它們。 (該功能會做得太多,但至少它可以在更少的開銷下正常工作。)

========================= ===============================================

我在我的模型中有這個代碼。這是一個計時器應用程序,啓動計時器時會觸發此代碼。基本上,任何運行定時器都應該暫停,並且某種程度上該視圖需要理解它應該刷新這些定時器。

public function start($input = array()) 
{ 
    if($timers = TimeLog::where('status','running')->get()){ 
     foreach($timers as $timer){ 
      /** @var $timer TimeLog **/ 
      $timer->pause(); 
     } 
    } 
    $this->user_id = Auth::user()->id; 
    $this->addDetails($input); 
    $this->restarted_at = date('Y-n-d H:i:s'); //TODO timezones 
    $this->status = 'running'; 
    $this->save(); 
} 

我不舒服從此函數返回暫停定時器的列表。只是似乎沒有道理。

我想過把foreach移動到我的控制器上,但這確實是業務邏輯,我想在啓動計時器時確保沒有運行計時器。

我可以在這個類中創建另一個方法,它可以解決返回問題,但是如何保證每次啓動調用將檢查運行計時器?

+1

你可以在你的模型中添加一個方法,'getPausedTimers'返回一個暫停計時器數組,或者可能只是暫停計時器的ID,如果你的設置是這樣的......我真的不明白這個程序的作用雖然。據我可以告訴這整個事情會更好,作爲JavaScript – samrap

+0

狀態保存在數據庫中。我發現上面提供了選項3,但這意味着要麼將要結合的進程(更好或更差)分開或保持耦合,然後從對象方法返回不相關的值。 – Stephane

+0

嗯。我認爲Laravel真的應該實現一個實際的業務層 – samrap

回答

1

這似乎很適合使用here所述的存儲庫模式。

我最近不得不解決一個類似的問題,因爲我剛剛開始使用Laravel,並將所有業務邏輯放在ModelController類中。我的業務邏輯似乎對其中任何一個都沒有意義,經過一些研究後,我發現Repositories

我會嘗試這樣的事:

class EloquentTimerRepository implements TimerRepository 
{ 
    /** 
    * Part of your TimerRepository interface 
    */ 
    public function startTimersForCurrentUser($inputs) 
    { 
     $this->pauseRunningTimers(); 
     $newTimer = $this->createNewTimer($inputs); 
     $newTimer->start(); 
    } 

    private function createNewTimer($inputs) 
    { 
     $timer = new Timer; 
     $timer->user_id = Auth::user()->id; 
     $timer->addDetails($input); 
     $timer->save(); 

     return $timer; 
    } 

    private function getRunningTimers() 
    { 
     return TimeLog::where('status','running'); 
    } 

    private function pauseRunningTimers() 
    { 
     if($this->getRunningTimers()){ 
      foreach($timers as $timer){ 
       /** @var $timer TimeLog **/ 
       $timer->pause(); 
      } 
     } 
    } 
} 

然後:

class Timer extends Model 
{  
    public function start() 
    { 
     $this->restarted_at = date('Y-n-d H:i:s'); //TODO timezones 
     $this->status = 'running'; 
     $this->save(); 
    } 
} 

至於更新視圖,你將不得不要麼做一個重新加載頁面或者如果你是使用ajax,進行後續調用以獲取最新的定時器,並根據該數據重置頁面元素。有很多方法可以實現推送(從服務器),但我還不熟悉這些技術。

+0

我在'createNewTimer()'和'start()'中分開了save()調用,但是你可以通過移動到一個函數來恢復使用一個函數, *創建計時器**和**啓動計時器**操作。 – Bryan

+0

謝謝你的回答。我的問題更多:如果我想暫停計時器作爲我的迴應的一部分,我應該在哪裏得到這個暫停的計時器列表?我不想提出一個單獨的請求(儘管使用zeromq我可以添加一個監聽器,並且可以完全解決這個問題)。 – Stephane