1

Consider the following view structure:

  • Layout View
    • Map View
    • List View
      • Item View
        • List View
          • Item View
          • Item View
      • Item View
        • List View
          • Item View
          • Item View

At the moment, I have only one controller for that entire structure. All the nested views communicate with that controller by bubbling events.

Would I want to create a controller for each level? What I've got works, but I feel like my layout view and list views are doing too much - e.g. when the controller says "here is an updated list of items (from the server)", the layout view is responsible for removing map markers that are not part of the new data, update existing ones, and add new ones. At the same time, the LayoutView's first ListView is responsible for doing the exact same, but for it's items.

Would it be a better idea to create a controller for each? If so, how would I go about it? Should the layout view get a ListController and a MapController injected, which would be responsible for constructing the child views?

If the tech is of interest: This is for a JavaScript widget.

apxcode
  • 7,696
  • 7
  • 30
  • 41
Jeff
  • 12,085
  • 12
  • 82
  • 152
  • This is a bit abstract and hard to understand without a code sample, so I can only give you an abstract answer in return. If your controller has a lot of methods/actions, that's OK if they all relate to the same concept and share a lot of code. If you find your controller using a lot of different view models, then that's a good sign that it's time for another controller. Let your design be driven by the SRP and DIP principles. – Jason Nesbitt May 13 '14 at 18:15
  • @JasonNesbitt as it is right now, all views that are being managed by the LayoutView, are using the LayoutView as their "controller". – Jeff May 14 '14 at 11:47
  • What did you end up doing? – Seth Jul 30 '14 at 15:02
  • I went with my original structure, as doing *pure* MVC would be over-arching for a self-contained widget that's supposed to be include -> `myWidget.create({with: 'some options'})`. – Jeff Jul 30 '14 at 15:05

1 Answers1

0

You have listed only a collection of views. If you are looking at implementing an MVC based widget library, you need to have corresponding models and controllers. That is, for each view you have, you need to have a model instance and a controller instance (you need to have corresponding classes coded).

For example, you will have ListModel, ListView and ListController classes. You might decide to code another class called List to bind everything together - so that your UI building code of the application simply instantiate the List class and use it. You can reduce the number of classes if you wish. For example, you may decide to join the View and Controller into one (because coupling between a view and controller is tight).

Similarly, you will have ItemModel, ItemView and ItemController classes (and also an Item class).

The model classes will have facilities to present your data to corresponding view classes in ways the corresponding view classes can use to render the specific views. The controllers will know how to interpret the UI interactions that happen on corresponding views and invoke methods on corresponding views and corresponding models.

To allow creation of the tree hierarchy, you will ideally use the GoF composition pattern.

Alternative to the MVC pattern, you may wish to look at PAC pattern where the responsibility assignment strategy is different. MVC is widely used nowadays.

  • 1
    I hear ya, so a View+Controller+Model for each "level". But how would I compose this? Should the LayoutController instantiate the MapController and the ListController? Or is this perhaps over-engineering things? – Jeff Jun 05 '14 at 09:21
  • To be clear, not "View+Controller+Model" for each level, but a "View+Controller+Model" for each component or widget (irrespective of whether they are composite components or leaves). As I said, think of a class that would compose all of them (M,V,C) to form a component (W). So W internally will instantiate M,V and C. The UI containment hierarchy can be build in terms of instantiated Ws in a given app. Instantiating Ms,Vs, and Cs is mostly a matter of component library creator. But Ws should facilitate application created Ms, Vs and Cs to be injected to them if customizations re needed. –  Jun 05 '14 at 13:04
  • This can be over-engineering if you only have one app to be supported by your widget library. But if your concern is not implementing a reusable or modifiable library of widgets or a very easily modifiable view for your app, then you need to think twice as to why you need to focus much on abstractions and separation of concerns. –  Jun 05 '14 at 13:14
  • I separate concerns because it is easier for me to maintain. The user of the widget knows nothing of the internals. – Jeff Jun 08 '14 at 19:55
  • Read this for clarity on using MVC when you implement a widget: [Is MVC a design pattern or an architectural pattern?](http://www.swview.org/blog/mvc-design-pattern-or-architectural-pattern) –  Jun 08 '14 at 20:20