开发者

MVC: Am I doing it right?

开发者 https://www.devze.com 2023-01-31 00:02 出处:网络
Hey people. I don\'t know if I understood 100% the MVC concept. I\'m having troubles with the Model-View relation.

Hey people. I don't know if I understood 100% the MVC concept.

I'm having troubles with the Model-View relation.

In order to present the data to the user, the View must have access to the data, right? Is this access obtained by passing all the needed data to the view directly (and having the view hold the data within its class as an attribute), or just obtain the data "parsed" as strings, integers, etc... as it is needed (as the user navigates through the GUI) from the controller, by raising events? I fee开发者_如何学JAVAl like this is a little bit event overkill, since the data hasn't changed.

BTW, can you tell me what those arrows on the MVC diagram on Wikipedia do on a real example? Thanks.


A view is for presentation purposes only. The controller is in charge of fielding requests from the UI and invoking the necessary methods in the model, which then present their outputs to the views.

The arrows denote relationships between the classes. The dotted lines are relationships between classes and interfaces while the solid lines denote direct relationships, meaning that the classes likely hold instance variables of the classes they are related to.


The model is the central, authoritative repository of information. As an example, take a church's directory of its congregation.

There are controllers into that model that inform the model of data that should be changed. As an example, a congregation member informs the church office when they move or change phone numbers, and the directory is updated.

There are also views into that model that use the data, but cannot make changes to it. As an example, one church member can get information about another from the directory.

Note that in some cases views and controllers can be the same thing, or views for one model, controllers for another, etc., etc. For example a church member can be a view into other members' data, or change their own by interacting with the model.

The important thing to keep in mind is who owns the authoritative version of the data. The invariant that it is the model that has the most timely, accurate and authoritative data means you know exactly where to go to get the information you need.

There are two basic ways a model can communicate with the views: pushing and pulling. Pushing the data involves intelligence on the model side to know which views should be notified when a piece of information has been updated. Pulling the data involves intelligence on the view side to know how and when to look at the model for changes to the data it is most interested in.


To build on the previous answers, here is a super simple application showing the various usage of each of the areas in question. This app stores and displays cars which a Salesman has sold.

First we have our models:

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; }
}

Now lets say we need to display a page which details all of the cars which a particular Salesman has sold. To do this we decide what data we will need on the page, e.g. Salesman name and a list of Car's which he has sold. We create a View Model of this data.

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

Now we need to build (populate) this View model in our controller ready to be passed to our 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);
}

Now all there is to do is just write this data out to our view, e.g.

@model MyProject.Web.Models.ViewModels.SalesViewModel

Salesman Name: @Model.SalesmanName

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


I believe I can add a little clarity. Basically you can use a Singleton pattern where only one instance of the model exists then you can use said Singleton within the View to bind things in your View to the model, that is you add listeners for changes to the model (in one sense or another) and the view updates itself whenever the model changes.

The model itself isn't affected directly by the view rather the view dispatches events or otherwise uses the controller to modify the model. This way you can have a common "shared" model a common controller which modifies said model and all sorts of views that display parts of said model in ways that make sense.

The views don't need to handle passing around data between one another in this way and the common functionality of modifying the model is contained in the controller. I had some trouble with these concepts when I first dove into them as well mostly because you never have 100% true separation of these parts, they are all related and will have a references to one another (via attached listeners at the least).

In Flex/AS3 my dev environment of choice this is very very easy to accomplish, you make on Model.as file that has a static variable called say modelLocator which is itself a new Model(), in the Model.as you define all your public variables, in Controller.as you have a handle on the model by creating a property (sure call it modelLocator here too) and within the controller's constructor you can instantiate the modelLocator like modelLocator=Model.modelLocator, do the same in your View then in the view you just update your view components when the model changes (in Flex you can use {} to bind values directly onto properties of your components, views pull from the model based on the post from @fbereto, good explanation btw).


From a high-level view, when you think about application architecture i.e. data layer, business logic layer and presentation layer, MVC should only be your presentation layer. I have often seen people make the mistake of thinking that in MVC, models represent their data layer, controllers represent the business logic layer and views represent the presentation layer.

You should always have a separate business logic layer (or services layer) which your MVC controllers access to carry out business logic, and also a separate data access layer (or repositories) which is only accessed by your services/business logic layer to retrieve data out of the database.

In your typical MVC application, you may have multiple view models representing the same data layer object (which typically represents a database table). For example, you may have 2 views for to represent information about a person; one is a summary view and the other is a details view. In your MVC application you will have 2 View Models i.e. PersonSummary and PersonDetail both of which are populated from the same Persons table in the data layer and are returned to your Controller Action when your controller calls methods (e.g. GetPersonSummary() and GetPersonDetails()) on the PersonService class (business logic layer).

Layering your applications in this way will make them far more maintainable and testable than treating your View Models as data models and writing all your business logic in the Controller actions.

This was my 2cents anyway! Hope it helps you understand MVC better...

0

精彩评论

暂无评论...
验证码 换一张
取 消