2013-10-12 68 views
1

我正在尋找更好地解釋MCV中的視圖層,特別是程序中的流程如何從控制器轉到視圖,重點放在控制器和視圖之間使用1:1關係時的模型狀態。控制器和視圖之間的1:1關係有什麼作用?

在所有示例中,我都看到數據正從控制器轉發到視圖,並且該視圖沒有執行任何特定操作,因此需要爲特定控制器編寫特定視圖。我誤解了1:1關係的口頭禪嗎?我發現最新的例子是在這裏貼些天回:https://stackoverflow.com/a/18983927/1681418

class View 
{ 
    public function render($templateFile, array $vars = array()) 
    { 
     ob_start(); 
     extract($vars); 
     require($templateFile); 

     return ob_get_clean(); 
    } 
} 

我試圖爲每個控制器創建特定視圖類,和我目前有從模型中提取所有數據,因爲它需要來看。它是乾淨的,因爲我有一個非常明確的do-stuff-to-the-the-model section(= controller)和只讀模型 section(= view)。然而,我有一些缺點,我還沒有找到一個整潔的解決方案,即:

  • 應該在哪裏選擇模板文件?
  • 視圖如何瞭解模型中的錯誤?
  • 該視圖如何瞭解控制器中成功或不成功的命令/操作?
  • 如何在出現錯誤時更改視圖?或者,當用戶狀態發生變化時,我該如何正確執行我的路由。

我沒有任何問題在我的頁面上顯示正確的輸出,但我目前的方法感覺錯誤。 **任何人都有一個視圖的例子,使用領域驅動的設計模型作爲圖層,而不是類? **

This answer與我通常發現的非常相似,我不明白這種方法如何使用或需要1:1的關係。

我主要是尋找的例子,而不是代碼審查,但我在任何情況下提取了一些我的代碼片段的例子。在這裏,我通過一個調度器調用控制器進行訪問控制和路由,然後通過同一個調度器再次查看訪問。如果是http請求,則視圖依次調用將數據分配給模板引擎的不同表示對象,如果是ajax請求,則爲json。

class Controller 
{ 
    public function login() 
    { 
     $this->serviceFactory 
      ->build('recognition') 
      ->authenticate($this->request->username, $this->request->password); 
    } 
} 

class View 
{ 
    public function login() 
    { 

     /** Prepare server response (i.e. state of the model) */ 
     $this->presentationObjectFactory 
      ->build('serverresponse', true) 
      ->setPresentationName('success') 
      ->assignData($this->serviceFactory->build('modelLog')->getModelResponse('success')); 

     /** Get current visitor information */ 
     $this->presentationObjectFactory 
      ->build('visitor', true) 
      ->assignData($this->serviceFactory->build('recognition')->getCurrentVisitor()); 

     return $this->serviceFactory->build('recognition')->getCurrentVisitor()->isLoggedIn() ? 
        $this->indexAction() : /* Reroute to index of view */ 
        $this->display('login.html'); /* Show the login template when unsuccesful login*/ 
    } 
} 

class PresentationObject 
{ 
    public function assignData(Collection $visitors) 
    { 
     $dateformat = new DateFormat(); 
     $dateTime = new \Datetime(); 

     foreach($visitors as $visitor) 
     { 
      $dateTime->setTimestamp($visitor->timestamp); 

      $this->assign_block_vars('visitor', array(
       'ID'    => $visitor->id, 
       'USERNAME'   => $visitor->user->Username, 
       'IP'    => $visitor->remote_addr, 
       'HTTP_USER_AGENT' => $visitor->http_user_agent, 
       'LAST_SEEN_ONLINE' => ucfirst($dateformat->formatDateDiff($dateTime)), 
       'DEVICE'   => $visitor->getDevice(), 
       'PLATFORM'   => $visitor->getPlatform(), 
       'BROWSER'   => $visitor->getBrowser(), 
      )); 
     } 
    } 
} 

我的MVC和領域驅動設計的認識和理解強烈由用戶tereško的影響,但我可能誤解了這一解釋的部分視圖東西...

+0

的[模板](http://codeangel.org/articles/simple-php-template- engine.html)應該由當前視圖根據您從模型中提取的數據進行選擇。錯誤狀態(將由來自控制器的失敗命令觸發)可以是所述數據的一種形式。如果遇到錯誤,在打開不存在的文章時,可以通過兩種方式處理:查看發送* HTTP位置*標題或查看選擇,而不是文檔顯示模板,用於傳遞錯誤消息的一些模板。 –

+0

@tereško將視圖注入控制器然後服務的目的是什麼?它僅僅是一個將數據推送到視圖的架構決策嗎?我看到你的帖子在這裏:http://stackoverflow.com/questions/5863870/how-should-a-model-be-structured-in-mvc/5864000#5864000你注入到控制器的視圖。 – bblue

+1

當前視圖被注入到控制器中,因爲用戶的命令並不總是以域模型爲目標。舉個例子:可摺疊的小部件。如果使用PHP作爲後備選項實現它們(如果JS不可用),那麼展開或摺疊該小部件將純粹是* UI邏輯*。控制器不僅可以改變模型的狀態,還可以(在極少數情況下)改變視圖的狀態。這就是爲什麼控制器有一個視圖作爲依賴。 –

回答

1

做些什麼目的控制器和視圖之間的1:1關係提供服務?

如果視圖可以應用於多個工作流環境/控制器/模型中,則不需要嚴格的1:1規則。即使將視圖和控制器分開使用,即使它們只能一起使用並且可以合併,也是明確區分責任的最佳實踐。這也使得以後更容易交換和分享視圖。

應該在哪裏選擇模板文件?

在你的情況你有一個View類,所以它應該在那裏定義。在一些系統中,模板的視圖,並且通常在控制器或配置文件中被選擇。

視圖如何瞭解模型中的錯誤? 視圖如何瞭解控制器中成功或失敗的命令/操作?

在某些體系結構中,模型在更新或任何其他操作期間將其問題返回給控制器。在控制器中,我通常會將任何問題添加到用戶消息堆棧中。然後在視圖中輸出這些消息給用戶。

如何在出現錯誤時更改視圖?或者,當用戶狀態發生變化時,我該如何正確執行我的路由。

這我見過很多不同的方式處理。最健壯的解決方案是讓您的控制器將下一個工作流程步驟傳遞給視圖。對於任何業務邏輯而言,視圖應基本上儘可能地保持不可知性。

任何示例代碼對於SO來說都太長和詳細。我有良好的MVC框架的教程開始:

+0

小心給我發一些真實生活的例子,我可以用最後兩點看看SO的離線?我已經瞭解到,我的做法或多或少都是合理的,但是我的代碼非常混亂,很可能是我悲傷的根源。 – bblue

+1

我所有的現實生活中的例子都屬於我的客戶,所以我不能分享他們。但是我已經添加了一些鏈接來說明一些框架如何處理驗證,這應該有助於解釋我的觀點。不幸的是,我從來沒有在互聯網上看到一個非常好的規則/工作流程示例(使用乾淨的MVC)。他們通常非常專業和複雜。 –

相關問題