badallen
badallen

Reputation: 1127

AngularJS Controller Design

I am currently evaluating AngularJS as a potential MVC framework. I am wondering on what the "correct" way to implement the following scenario is -

Say I am designing an User detail page. It is broken down into different tabs like basic information tab(name, email...), user interests tab(drop downs like sports, music..), etc.

So the code looks like this:

                    <!-- main.html-->
                    <div ng-controller="UserController">
            <div ng-switch on="renderPath">
                <div ng-switch-when="basicInfo">
                     <div ng-include src="basicUrl"></div>
                </div>
                <div ng-switch-when="interests">
                     <div ng-include src="interestUrl"></div>
                </div>
            </div>
        </div>

and interests.html looks like

    <div>
        <div class="dropdown">
            <a class="dropdown-toggle" id="dLabel" role="button" data-toggle="dropdown" data-target="#" href="/page.html">
            I like to play:
             </a>
            <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
                <li ng-repeat="sport in sports">{{sport}}</li>
            </ul>
            <a class="dropdown-toggle" id="A1" role="button" data-toggle="dropdown" data-target="#" href="/page.html">
            I like to listen to:
            </a>
            <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
                <li ng-repeat="genre in genres">{{genre}}</li>
            </ul>
        </div>
    </div>  

So the question is, asides from the UserController, should I create a separate controller for the "basicInfo" and "interests" tabs? The reason why I may want to create InterestsController is because I don't necessary think

$scope.sports= ['baseball', 'bastketball'];
$scope.genres= ['pop', 'classical'];

should live in the UserController since only Interest.html cares about the different selections of interests. Also UserController may get real fat real quick since the page will have many other tabs.

But at the same time, in Angular's documentation - *"In Angular, a model is any data that is reachable as a property of an angular Scope object"*, I feel like if I do then have an InterestsController, etc, its model is rather arbitrary since it is just containing the information needed for that tab only.

So what's the best practice? I hope I explain myself clearly. Thank you.

Upvotes: 3

Views: 1521

Answers (1)

Mark Rajcok
Mark Rajcok

Reputation: 364677

Here's one approach to designing an Angular app:

  1. Think about your models (e.g., User). Create services for those models.
  2. Think about how you want to view your models -- your views (e.g., user-main (tabbed), user-basic, user-interests). Create HTML templates for those views.
  3. Lastly, attach a controller to each view (using ng-view and routing, or ng-controller for every other way, such as what you are doing with ng-switch and ng-include). Have the controller find/get only whatever model data the view needs to do its job.
    "Make controllers as thin as possible" -- this was said somewhere in the DoubleClick talk.

For your particular example, I think the basicInfo and interests tabs should have their own controllers, because they are two distinct views. Note that each page can have multiple views on it -- all visible, or only some. How big or small a "view" is is up to you.

There is confusion about $scope, model, and services. Misko says in this YouTube video that "Scope is not your model. Scope is what you attach your model to."
In a comment exchange with Brandon Tilley, he had this to say about putting your models into services: "Services are especially good for model objects because they can be injected, and thus easily mocked in tests."

Upvotes: 5

Related Questions