2010-12-17 88 views
2

嘿人。我不知道我是否理解100%的MVC概念。MVC:我做對了嗎?

我遇到了Model-View關係的問題。

爲了呈現的數據給用戶,查看必須能夠訪問數據,對吧? 該訪問是通過將所有需要的數據直接傳遞給視圖(並使視圖將其數據作爲屬性保存在其類中),或者只是將數據「parsed」作爲字符串,整數等來獲取。是否需要(在用戶通過GUI導航時)通過提升事件來控制器?因爲數據沒有改變,我覺得這是一件有點過度的事情。

順便說一句,你能告訴我在維基百科上的MVC圖上的那些箭頭上一個真實的例子嗎?謝謝。

+0

請,你會怎麼做: 1.使視圖召開類別裏面的數據,所以它會自動更新本身 2.引發一個事件,使控制器更新組合框與列表從數據中獲得的字符串(通過視圖上的適當的公共方法) Isnt是否使用單例使數據可用於視圖與此模式相矛盾?或者可以,只要我們從單身人士那裏獲得東西? – dfdfdffd 2010-12-18 07:12:20

回答

4

視圖僅用於演示目的。控制器負責調用UI的請求並調用模型中的必要方法,然後將其輸出呈現給視圖。

箭頭表示類之間的關係。虛線是類和接口之間的關係,而實線表示直接關係,這意味着這些類可能擁有與它們相關的類的實例變量。

+0

謝謝你,我的第一個選擇是這樣嗎? – dfdfdffd 2010-12-17 23:09:46

+0

@dfdfdffd對你的第一個問題是的 – Bnjmn 2010-12-17 23:42:47

4

該模型是中央,權威的信息存儲庫。作爲一個例子,拿一個教會的教會目錄。

有控制器進入該模型,通知模型應該改變的數據。例如,會衆成員在移動或更改電話號碼時通知教堂辦公室,並更新目錄。

也享有成模型,使用數據,但不能進行更改。舉個例子,一位教會成員可以從目錄中獲得關於他人的信息。

注意,在某些情況下,視圖和控制器可以是相同的東西,或觀看一個模型中,控制器爲另一個,等等,等等。例如教堂構件可以是一個視圖到其它成員的數據,或改變他們通過與模型進行交互。

要記住的重要一點是誰擁有權威版本的數據。不變的是,它是具有最及時,準確和權威性數據的模型,意味着您確切知道去哪裏獲取所需的信息。

模型可以通過兩種基本方式與視圖進行交流:推拉。 推動數據涉及模型方面的情報,以知道在更新信息時應通知哪些視圖。 拉動該數據涉及到視圖方面的情報,以知道如何以及何時查看模型,以改變其最感興趣的數據。

+0

謝謝你,喜歡推拉比喻。 因此,如果視圖拉動信息並且知道所有數據和關於數據的任何事情,那麼它是否可以?或者這是不是建議? – dfdfdffd 2010-12-17 23:39:34

+0

你能回答這個嗎?我認爲我所有的疑慮都會以一個很好的答案消失:假設視圖必須使用模型中的數據更新組合框。你會怎麼做? 1.使視圖保存類中的數據,因此它自動更新自己2.提出事件並使控制器用從數據中獲取的字符串列表更新組合框(通過視圖上的適當公共方法) – dfdfdffd 2010-12-17 23:47:46

0

我相信我可以增加一點清晰度。基本上你可以使用Singleton模式,其中只有一個模型實例存在,那麼你可以在View中使用Singleton來將視圖中的東西綁定到模型上,也就是爲模型中的變化添加監聽器(在某種意義上或另一種意義上),並且視圖在模型更改時自動更新。

模型本身並不直接由視圖,而視圖調度事件或以其他方式使用的控制器來修改模型的影響。通過這種方式,您可以擁有一個共同的「共享」模型,它是一種通用控制器,它可以修改所述模型以及以有意義的方式顯示所述模型的各個部分的各種視圖。

視圖不需要處理以這種方式在彼此之間傳遞數據,並且修改模型的通用功能包含在控制器中。當我第一次接觸這些概念時,我遇到了一些麻煩,主要是因爲你從來沒有100%真正的這些部分的分離,它們都是相關的,並且會相互引用(至少通過附加的聽衆)。

在Flex/AS3中,我的開發環境非常容易實現,您可以在Model.as文件中創建一個名爲say modelLocator的靜態變量,它本身就是Model.as中的一個新Model()你可以在Controller.as中定義所有的公共變​​量,通過創建一個屬性(在這裏也可以稱之爲modelLocator),並且在控制器的構造函數中你可以實例化modelLocator,比如modelLocator = Model.modelLocator,做同樣的事情在視圖中,然後在視圖中更新視圖組件(在Flex中,您可以使用{}將值直接綁定到組件的屬性上,視圖根據@fbereto中的帖子從模型中拉出,好的解釋BTW)。

+0

但什麼是阻止視圖使用單例數據實例來修改數據以及獲取數據來生成視圖? 或者它應該是這樣的 – dfdfdffd 2010-12-18 07:36:11

0

從高層次看,當您考慮應用程序體系結構即數據層,業務邏輯層和表示層時,MVC應該只是您的表示層。我經常看到人們犯了一個錯誤,認爲在MVC中,模型代表數據層,控制器代表業務邏輯層,視圖代表表示層。

您應該始終有一個單獨的業務邏輯層(或服務層),您的MVC控制器可以訪問該業務邏輯層來執行業務邏輯,並且還應該有一個單獨的數據訪問層(或存儲庫),只有您的服務/業務邏輯層從數據庫中檢索數據。

在典型的MVC應用程序中,可能有多個視圖模型表示同一個數據層對象(通常代表數據庫表)。例如,您可能有2種觀點來表示關於某人的信息;一個是摘要視圖,另一個是詳細視圖。在您的MVC應用程序中,您將擁有2個視圖模型,即PersonSummary和PersonDetail,這兩個視圖模型都是從數據層中的相同人員表中填充的,並在控制器調用方法(例如GetPersonSummary()和GetPersonDetails())時返回到Controller Action在PersonService類(業務邏輯層)上。

以這種方式分層您的應用程序將使它們比將視圖模型視爲數據模型並將所有業務邏輯寫入控制器操作中更具可維護性和可測試性。

無論如何,這是我的2cents!希望它可以幫助你更好地理解MVC ...

1

爲了在前面的答案的基礎上,這裏是一個超級簡單的應用程序,顯示每個有問題的區域的各種用法。這個應用程序存儲和顯示推銷員出售的汽車。

首先,我們有我們的模型:

public class Car 
{ 
    int Id { get; set; } 

    string make { get; set; } 
    string colour { get; set; } 
} 

public class Salesman 
{ 
    int Id { get; set; } 

    string name { get; set; } 
    IList<Sale> Sales { get; set; } 
} 

public class Sale 
{ 
    int Id { get; set; } 

    int CarId { get; set; } 
    int SalesmanId { get; set; } 

    decimal Amount { get; set; } 
} 

現在讓我們說,我們需要顯示一個網頁,詳細介紹所有這些特定的推銷員已經售出的汽車。要做到這一點,我們決定我們需要在頁面上顯示哪些數據,例如推銷員姓名和他賣出的汽車列表。我們創建了這個數據的一個View Model

public class SalesViewModel 
{ 
    string SalesmanName { get; set; } 
    List<Car> CarsSold { get; set; } 
} 

現在我們需要在我們的控制器中構建(填充)這個View模型,以便傳遞給我們的View。

public ActionResult SalesmanCarsSold(int salesmanId) 
{ 
    SalesViewModel salesVm = new SalesViewModel(); 

    using (var dbCtx = new dbCtx()) 
    { 
     salesVm.SalesmanName = dbCtx.GetSalesmanById(salesmanId).Name; 
     salesVm.CarsSold = dbCtx.GetCarsSoldBySalesmanId(salesmanId); 
    } 

    return View(salesVm); 
} 

現在所有要做的就是將這些數據寫入我們的視圖,例如,

@model MyProject.Web.Models.ViewModels.SalesViewModel 

Salesman Name: @Model.SalesmanName 

@foreach(var car in Model.CarsSold) 
{ 
    Car: @car.make 
}