Search code examples
javascriptangularjsangularjs-ng-repeatangularjs-routing

Angularjs - ng-view inside ng-repeat


I have a list of Products. For each one, I have buttons to show the details and comments about it inside this ng-view.

The user must to see in one pege the details about all products available, for example.

Here is the HTML list:

<div ng-controller="ProductsApp">
    <ul>
      <li ng-repeat="product in products">
        <p>{{product.Name}}</p>
        <p>
            <a href="#/details/{{product.Id}}">Details</a>
            <a href="#/comments/{{product.Id}}">Comments</a>
        </p>
        <div ng-view="productView{{product.Id}}">
        </div>
      </li>
    </ul>
</div>

Then my routing:

angular
    .module('ProductsApp',[])
    .config(function ($routeProvider) {
        $routeProvider.
            when('/details/:productId', {
                controller : DetailsCtrl, 
                templateUrl : 'Details.html',
                view: 'productView:productId'
            }).            
            when('/comments/:productId', {
                controller : CommentsCtrl, 
                templateUrl : 'Comments.html',
                view: 'productView:productId'
            }).

My controller:

function DetailsCtrl ($scope, $window, $http, DetailsList) {    
    var productId = $routeParams.productId;
    $scope.Details[productId] = DetailsList.get({'productId' : productId});
}

And finally the Details.html

<div>
    Name: {{Details[productId].Name}}
    Size: {{Details[productId].Size}}
    ...
</div>

Two questions about it:

  1. Is it a right approach? Is there any other way to do it?
  2. How can I get the productId for the actual ng-view? Name: {{Details[productId].Name}}

Thank you!!!


Solution

  • There may be a way to make it work along the lines you're attempting, but I think it's a more complicated approach than you need. Angular really seems to expect one route at a time per controller, and working around that is likely to involve something hackish.

    Instead, look at the tabs example on the front page at http://angularjs.org/. I'd handle this with a directive, though you could do without it. Something like this (off the cuff, so this may not work yet precisely as written):

    <span ng-click='showDetails[$index] = true'>Details</span>
    <span ng-click='showDetails[$index] = false'>Comments</span>
    
    <div ng-show='showDetails[$index]'>Details here.</div>
    <div ng-show='!showDetails[$index]'>Comments here.</div>
    

    If you have behavior for the Details and Comments that require controllers, then I would go with directives. Write a directive for each (each with its own controller) and then the above just becomes something like:

    <span ng-click='showDetails[$index] = true'>Details</span>
    <span ng-click='showDetails[$index] = false'>Comments</span>
    
    <details ng-show='showDetails[$index]'> data-id='{{product.id}}'></details>
    <comments ng-show='!showDetails[$index]'> data-id='{{product.id}}'></comments>