3

I'm sure I'm doing something wrong and maybe trying to insert multiple controllers on a view is bad (At least I feel it might be bad), but wanted to get an opinion on the better approach.

My files are laid out as:

app.js

angular
  .module('gemstoreApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch'
  ])
  .config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'    <---- THIS is where I wish to insert a panelController
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });

main.js

angular.module('gemstoreApp')
  .controller('MainCtrl', function ($scope) {

    var gems = [
      {
        name: 'Gem1',
        price: 2.95,
        soldOut: false,
        images: [
          'img1.png'
        ],
        description: 'Some description'
      }, {
        name: 'Gem2',
        price: 1.00,
        soldOut: true,
        images: [
          'img2.png'
        ],
        description: 'Some tetra description'
      }, {
        name: 'Gem3',
        price: 5.00,
        soldOut: false,
        images: [
          'img3.png'
        ],
        description: 'Some tetra description'
      }
    ]

    $scope.products = gems;

  });

main.html

    <div>
        <ul>
            <div ng-repeat="product in products">
                <li>
                <p>{{ product.name }} - {{ product.price | currency }} - {{ product.description }}</p>
                <img ng-src="{{ product.images[0] }}" alt="">
                <button ng-hide="product.soldOut" class='btn btn-primary'>Add to Cart</button>
                <button ng-show="product.soldOut" class='btn btn-danger'>Sold Out!!!</button>
                </li>

<!== THE "tab" code from here is dirty .. and I'd like ot move it to its own controller ==>
                <section ng-init="tab = 1"> 
                    <ul class="nav nav-pills">
                        <li ng-class="{ active:tab === 1}"><a href ng-click="tab = 1">Description</a></li>
                        <li ng-class="{ active:tab === 2}"><a href ng-click="tab = 2">Specifications</a></li>
                        <li ng-class="{ active:tab === 3}"><a href ng-click="tab = 3">Reviews</a></li>
                    </ul>
                </section>
                <div id="panel" ng-show="tab == 1">
                    <h4>Description</h4>
                    <blockquote> {{ product.description }} </blockquote>
                </div>
                <div id="panel" ng-show="tab == 2">
                    <h4>Specification</h4>
                    <blockquote>Nothing yet</blockquote>
                </div>
                <div id="panel" ng-show="tab == 3">
                    <h4>Reviews</h4>
                    <blockquote>Nothing yet</blockquote>
                </div>
            </div>
        </ul>
    </div>

I'm mainly trying to refactor the "tab" code out of here and into a separate controller (panelCtrl) and use that in here. So I could do something like:

<li ng-class="{ active:panelCtrl.isSelected(1)}"><a href ng-click="panelCtrl.setSelected(1)">Description</a></li>

For those familiar, I'm going over the Angular tutorial by codeschool, and trying to do that with Yeoman.

Prashant
  • 1,014
  • 11
  • 28

1 Answers1

2

You can add another controller to the view by placing it directly into the html files like such: <div ng-controller="PanelCtrl as panel">.

However, perhaps creating a directive for your panel might be a better solution? Directives to can have controllers. This will let you use your panels in more views as well.

Having multiple controllers in one view in of itself is not "bad practice". But that doesn't mean making views with multiple controllers every time is "good practice". In this case, it seems that wrapping your panel into a directive would be the best.

PS: The fact that you've used yeoman makes no difference :).

Update for comment:

There are some pretty good resources when deciding a structure for your angular app and some of the answers can be found in the AngularJS application file structure answers. There is also this community driven angular-style-guide.

Community
  • 1
  • 1
Kirill Fuchs
  • 13,446
  • 4
  • 42
  • 72
  • Thanks for the reply Kiril. It makes sense that Yeoman make no difference. It was just to make the code structuring more recognizable for someone familiar to Yeoman. re: the controller: Should I be defining it in `main.js` or its own file? What is the best practice for this. Can you give me a rough outline on how I should be thinking when structuring the code. – Prashant Jan 03 '15 at 04:51
  • 1
    @Prashant Added to my answer with references. – Kirill Fuchs Jan 03 '15 at 06:51