AngularJS将ui-view嵌套到ng-repeat中

Dav*_*ani 7 javascript nested angularjs angularjs-ng-repeat angular-ui-router

我正在使用Spotify API创建一个应用程序.此应用程序可以:1.通过输入字段按艺术家名称查找专辑2.一旦显示专辑,用户可以单击专辑的标题并查看其曲目

我创建了2个视图:1.专辑视图2.曲目视图,专辑视图的子视图.

我想将特定点击专辑的曲目ui-view(带有ID)显示到专辑的ng-repeat中,但结果是我在所有专辑列表中都有相同的专辑曲目列表.如何将专辑的曲目ui-view显示在由ng-repeat指令导致的点击专辑容器中?

这是代码.

路由:

------
.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'
      });
})
-----
Run Code Online (Sandbox Code Playgroud)

相册视图:

<div ng-if="albums.items">
    <h1>{{searchedArtist}}'s 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>
Run Code Online (Sandbox Code Playgroud)

主要专辑控制器:

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;
    });
  };
});
Run Code Online (Sandbox Code Playgroud)

轨道控制器:

angular.module('spotifyAngularApp')
.controller('TracksCtrl', function ($scope, $stateParams, spotifyService) {
    console.log($stateParams);
    spotifyService.albumTracks($stateParams.id).then(function(data){
        $scope.tracks = data.items;
      });
});
Run Code Online (Sandbox Code Playgroud)

Kha*_* TO 11

你想要做的事情没有意义.状态可能有多个与之关联的视图,但这些视图必须是预定义的,而不是动态生成的.

静态定义唯一1个视图的代码之间存在冲突:

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

并在您的代码动态生成用户界面视图ng-repeat.没有逻辑可以说明ui-view要将html加载到哪个.在这种情况下,我建议只有1 ui-view移动它ng-repeat:

<div ng-if="albums.items">
    <h1>{{searchedArtist}}'s 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>
Run Code Online (Sandbox Code Playgroud)

或者,如果ng-repeat由于布局页面的方式确实需要将其放入内部,请尝试ng-if确保仅显示1 ui-view.(this is a workaround and not recommended)

<div ng-if="albums.items">
        <h1>{{searchedArtist}}'s 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>
Run Code Online (Sandbox Code Playgroud)

并修改你MainCtrl的注入,$state以便我们可以在视图中访问它:

angular.module('spotifyAngularApp')
.controller('MainCtrl', function ($scope, spotifyService, $state) {
  $scope.$state = $state;

  //your code
});
Run Code Online (Sandbox Code Playgroud)


Jos*_*ley 4

不幸的是,您尝试做的事情并没有真正意义。您的意思是“重复此状态(相册)视图的次数等于收藏相册中的项目数”。但是,当您单击锚点时,您将告诉 album.tracks状态去获取具有您单击的专辑 ID 的专辑。然后,这将在专辑视图中的每个 ui 视图中显示 album.tracks 状态(这就是您所看到的)。

单个状态不能像您在此处尝试执行的那样在同一页面上多次“实例化”。请参阅此问题以获取更多信息:Does Angular JS support Routing of multiple views on the same page

我建议以不同的方式构建它 - 如果您需要将模板分开,也许可以使用 ng-repeat 和 ngInclude 。否则,在一页上构建整个模板可能更容易,对所有专辑和曲目进行 ng-repeat,然后隐藏所有模板并在通过 ngHide/ngShow 单击时显示每个模板。