AngularJS nested u-view in ng-repeat

I am building an application with the Spotify API. the application can do: 1. Find albums by artist name through the input field 2. After the albums are shown, the user can click on the album name and see the tracks of this album

I created 2 views: 1. view albums 2. View tracks, view child albums.

I would like to show the ui-view tracks of a particular clicked album - with ID - into ng-repeat albums. but the result is that I have the same list of tracks by click on the entire list of albums. how can I show the ui-view landscape track in a container with a click that is the result of the ng-repeat directive?

here is the code:

Route:

------ .config(function ($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise('/'); $stateProvider .state('albums', { url: '/', templateUrl: 'views/main.html', controller: 'MainCtrl' }). state('albums.tracks', { url: ':id/tracks', templateUrl: 'views/tracks.html', controller: 'TracksCtrl' }); }) ----- 

Browse Albums:

 <div ng-if="albums.items"> <h1>{{searchedArtist}} Album List:</h1> <!-- albums ng-repeat --> <div ng-repeat="album in albums.items | unique:'name'" id="{{album.id}}"> <img ng-src="{{album.images[1].url}}" width="100"> <!-- the action to translate the state to tracks view --> <a ui-sref="albums.tracks({id : album.id})">{{album.name}}</a> <!-- tracks view --> <div ui-view></div> </div> 

Main Album Controller:

 angular.module('spotifyAngularApp') .controller('MainCtrl', function ($scope, spotifyService) { var options = { 'limit': 10 }; $scope.searchAlbums= function () { var sanitizeArtist = $scope.artist.split(' ').join('+'); $scope.searchedArtist = $scope.artist; spotifyService.search(sanitizeArtist, 'album', options).then(function(data) { $scope.albums = data.albums; }); }; }); 

Track Controller:

 angular.module('spotifyAngularApp') .controller('TracksCtrl', function ($scope, $stateParams, spotifyService) { console.log($stateParams); spotifyService.albumTracks($stateParams.id).then(function(data){ $scope.tracks = data.items; }); }); 
+7
javascript angularjs nested angularjs-ng-repeat angular-ui-router
source share
3 answers

What you are trying to do does not make sense. A state can have several views associated with it, but these views must be predefined and not dynamically generated .

There is a conflict between the code in which you statically define only 1 view :

 state('albums.tracks', { url: ':id/tracks', templateUrl: 'views/tracks.html', controller: 'TracksCtrl' }); 

and code in which you generate ui-view dynamically with ng-repeat . There is no logic to say which ui-view load your html. In this case, I suggest having only 1 ui-view , moving it from ng-repeat :

 <div ng-if="albums.items"> <h1>{{searchedArtist}} Album List:</h1> <!-- albums ng-repeat --> <div ng-repeat="album in albums.items | unique:'name'" id="{{album.id}}"> <img ng-src="{{album.images[1].url}}" width="100"> <!-- the action to translate the state to tracks view --> <a ui-sref="albums.tracks({id : album.id})">{{album.name}}</a> </div <!-- tracks view --> <div ui-view></div> </div> 

Or, if you really need to put it inside ng-repeat because of how you place your page, try ng-if to make sure that only 1 ui-view displayed. (this is a workaround and not recommended)

 <div ng-if="albums.items"> <h1>{{searchedArtist}} Album List:</h1> <!-- albums ng-repeat --> <div ng-repeat="album in albums.items | unique:'name'" id="{{album.id}}"> <img ng-src="{{album.images[1].url}}" width="100"> <!-- the action to translate the state to tracks view --> <a ui-sref="albums.tracks({id : album.id})">{{album.name}}</a> <!-- tracks view --> <div ng-if="$state.is('albums.tracks',{id : album.id})" ui-view></div> </div> </div> 

and change your MainCtrl to enter $state so that we have access to it in the view:

 angular.module('spotifyAngularApp') .controller('MainCtrl', function ($scope, spotifyService, $state) { $scope.$state = $state; //your code }); 
+11
source share

Unfortunately, what you are trying to do does not really make sense. What you say with this is "repeat this state (albums), which several times coincides with the number of items in collectible albums." But then, when you click on the anchor, you say that the status of album.tracks allows you to get the album with the ID of the album you clicked on. Then the status of album.tracks will be displayed in each ui-view in the album view (this is what you see).

One state cannot be "instanced" several times on the same page as you are trying to do here. See This Question for More Information: Does Angular JS Support Multiple View Routing on One Page

I would suggest building it differently - perhaps using ng-repeat with ngInclude inside if you need to save your template separately. Otherwise, it is possible to simply create the entire template on one page, ng-repeat for all albums and tracks, then hide everything and show each one by clicking through ngHide / ngShow.

+4
source share

If you need to create multiple views inside ng-repeat, would it be better to create a directive?

+3
source share

All Articles