控制器未定义

时间:2015-10-22 04:08:30

标签: javascript angularjs controller spotify

提前感谢您的帮助。我是Angular的新手,也是Javascript的新手,我遇到了一个我似乎无法解决的问题。

出于某种原因,WebStorm告诉我我的导入控制器没有定义。我是从另一个已导入的文件引用它的。我尝试将Spotify API与angular-js web包装器一起使用。

的index.html

<!DOCTYPE html>
<html ng-app='app'>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
    <script src="spec/lib/angular-spotify/src/angular-spotify.js"></script>
    <script src="spec/lib/angular-spotify/examples/main.controller.js"></script>
    <title>angular-spotify demo!</title>
    <style>
        ul {
            list-style: none;
        }

        .media {
            display: table;
            width: 100%;
        }

            .media img {
                display: table-cell;
                max-width: 100%;
            }

        .media-details {
            padding-left: 1em;
            vertical-align: middle;
            display: table-cell;
            width: 90%;
        }
    </style>
</head>
<body ng-controller='test'>
    <script>
        var app = angular.module('app');
        app.controller('test');
    </script>
    <!--<button ng-click="login()">Login with Spotify</button>
    <button ng-click="login()">Login with Spotify</button>
    <input type="text" ng-model="searchartist" ng-change="searchArtist()" placeholder="Search for an artist">
    <ul>
        <li ng-repeat="artist in artists">
            <a class="media" ng-href="{{artist.external_urls.spotify}}" target="_blank">
             <img ng-src="{{artist.images[0].url}}" alt="">
                 <div class="media-details">
                {{artist.name}}
                 </div>
            </a>
        </li>
    </ul>-->
    <script>
        asdf = test.getAlbum();
        console.log(asdf);
    </script>
    <h1>hello</h1>
    <h1></h1>
    <h1>hellooo</h1>
</body>
</html> 

main.controller.js

angular
  .module('app', ['spotify'])
  .config(function (SpotifyProvider) {
    SpotifyProvider.setClientId('3ab9db5d12614f7c9af32000adeafe1d');
    SpotifyProvider.setRedirectUri('callback.html');
    SpotifyProvider.setScope('user-read-private playlist-read-private playlist-modify-private playlist-modify-public');
  })
  .controller('test', ['$scope', 'Spotify', function($scope, Spotify) {

    $scope.searchArtist = function () {
      Spotify.search($scope.searchArtist, 'artist').then(function (data) {
        $scope.artists = data.artists.items;
      });
    };

    $scope.login = function () {
      Spotify.login().then(function (data) {
        console.log(data);
        alert("You are now logged in");
      }, function () {
        console.log('didn\'t log in');
      })
    };

    // Gets an album
    Spotify.getAlbum('0sNOF9WDwhWunNAHPD3Baj').then(function (data){
      console.log('=================== Album - ID ===================');
      return data.name;
    });
    // Works with Spotify uri too
    Spotify.getAlbum('spotify:album:0sNOF9WDwhWunNAHPD3Baj').then(function (data){
      console.log('=================== Album - Spotify URI ===================');
      console.log(data);
    });

    //Get multiple Albums
    Spotify.getAlbums('41MnTivkwTO3UUJ8DrqEJJ,6JWc4iAiJ9FjyK0B59ABb4,6UXCm6bOO4gFlDQZV5yL37').then(function (data) {
      console.log('=================== Albums - Ids ===================');
      console.log(data);
    });
    Spotify.getAlbums(['41MnTivkwTO3UUJ8DrqEJJ','6JWc4iAiJ9FjyK0B59ABb4','6UXCm6bOO4gFlDQZV5yL37']).then(function (data) {
      console.log('=================== Albums - Array ===================');
      console.log(data);
    });


    Spotify.getAlbumTracks('41MnTivkwTO3UUJ8DrqEJJ').then(function (data) {
      console.log('=================== Album Tracks - ID ===================');
      console.log(data);
    });
    Spotify.getAlbumTracks('spotify:album:41MnTivkwTO3UUJ8DrqEJJ').then(function (data) {
      console.log('=================== Album Tracks - Spotify URI ===================');
      console.log(data);
    });



    //Artist
    Spotify.getArtist('0LcJLqbBmaGUft1e9Mm8HV').then(function (data) {
      console.log('=================== Artist - Id ===================');
      console.log(data);
    });
    Spotify.getArtist('spotify:artist:0LcJLqbBmaGUft1e9Mm8HV').then(function (data) {
      console.log('=================== Artist - Spotify URI ===================');
      console.log(data);
    });

    Spotify.getArtistAlbums('0LcJLqbBmaGUft1e9Mm8HV').then(function (data) {
      console.log('=================== Artist Albums - Id ===================');
      console.log(data);
    });

    Spotify.getArtistAlbums('spotify:artist:0LcJLqbBmaGUft1e9Mm8HV').then(function (data) {
      console.log('=================== Artist Albums - Spotify URI ===================');
      console.log(data);
    });

    Spotify.getArtistTopTracks('0LcJLqbBmaGUft1e9Mm8HV', 'AU').then(function (data) {
      console.log('=================== Artist Top Tracks Australia ===================');
      console.log(data);
    });

    Spotify.getRelatedArtists('0LcJLqbBmaGUft1e9Mm8HV').then(function (data) {
      console.log('=================== Get Releated Artists ===================');
      console.log(data);
    });


    //Tracks
    Spotify.getTrack('0eGsygTp906u18L0Oimnem').then(function (data) {
      console.log('=================== Track ===================');
      console.log(data);
    });

    Spotify.getTracks('0eGsygTp906u18L0Oimnem,1lDWb6b6ieDQ2xT7ewTC3G').then(function (data) {
      console.log('=================== Tracks - String ===================');
      console.log(data);
    });

    Spotify.getTracks(['0eGsygTp906u18L0Oimnem','1lDWb6b6ieDQ2xT7ewTC3G']).then(function (data) {
      console.log('=================== Tracks - Array ===================');
      console.log(data);
    });

  }]);

角spotify.js

(function (window, angular, undefined) {
  'use strict';

  angular
    .module('spotify', [])
    .provider('Spotify', function () {

      // Module global settings.
      var settings = {};
      settings.clientId = null;
      settings.redirectUri = null;
      settings.scope = null;
      settings.authToken = null;

      this.setClientId = function (clientId) {
        settings.clientId = clientId;
        return settings.clientId;
      };

      this.getClientId = function () {
        return settings.clientId;
      };

      this.setAuthToken = function (authToken) {
        settings.authToken = authToken;
        return settings.authToken;
      };

      this.setRedirectUri = function (redirectUri) {
        settings.redirectUri = redirectUri;
        return settings.redirectUri;
      };

      this.getRedirectUri = function () {
        return settings.redirectUri;
      };

      this.setScope = function (scope) {
        settings.scope = scope;
        return settings.scope;
      };

      var utils = {};
      utils.toQueryString = function (obj) {
        var parts = [];
        angular.forEach(obj, function (value, key) {
          this.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
        }, parts);
        return parts.join('&');
      };

      /**
       * API Base URL
       */
      settings.apiBase = 'https://api.spotify.com/v1';

      this.$get = ['$q', '$http', '$window', function ($q, $http, $window) {

        function NgSpotify () {
          this.clientId = settings.clientId;
          this.redirectUri = settings.redirectUri;
          this.apiBase = settings.apiBase;
          this.scope = settings.scope;
          this.authToken = settings.authToken;
          this.toQueryString = utils.toQueryString;
        }

        function openDialog (uri, name, options, cb) {
          var win = window.open(uri, name, options);
          var interval = window.setInterval(function () {
            try {
              if (!win || win.closed) {
                window.clearInterval(interval);
                cb(win);
              }
            } catch (e) {}
          }, 1000);
          return win;
        }

        NgSpotify.prototype = {
          api: function (endpoint, method, params, data, headers) {
            var deferred = $q.defer();

            $http({
              url: this.apiBase + endpoint,
              method: method ? method : 'GET',
              params: params,
              data: data,
              headers: headers
            })
            .success(function (data) {
              deferred.resolve(data);
            })
            .error(function (data) {
              deferred.reject(data);
            });
            return deferred.promise;
          },

          _auth: function (isJson) {
            var auth = {
              'Authorization': 'Bearer ' + this.authToken
            };
            if (isJson) {
              auth['Content-Type'] = 'application/json';
            }
            return auth;
          },

          /**
           * Search Spotify
           * q = search query
           * type = artist, album or track
           */
          search: function (q, type, options) {
            options = options || {};
            options.q = q;
            options.type = type;

            return this.api('/search', 'GET', options);
          },

          /**
            ====================== Albums =====================
           */

          /**
           * Gets an album
           * Pass in album id or spotify uri
           */
          getAlbum: function (album) {
            album = album.indexOf('spotify:') === -1 ? album : album.split(':')[2];

            return this.api('/albums/' + album);
          },

          /**
           * Gets an album
           * Pass in comma separated string or array of album ids
           */
          getAlbums: function (albums) {
            albums = angular.isString(albums) ? albums.split(',') : albums;
            angular.forEach(albums, function (value, index) {
              albums[index] = value.indexOf('spotify:') > -1 ? value.split(':')[2] : value;
            });
            return this.api('/albums', 'GET', {
              ids: albums ? albums.toString() : ''
            });
          },

          /**
           * Get Album Tracks
           * Pass in album id or spotify uri
           */
          getAlbumTracks: function (album, options) {
            album = album.indexOf('spotify:') === -1 ? album : album.split(':')[2];

            return this.api('/albums/' + album + '/tracks', 'GET', options);
          },

          /**
            ====================== Artists =====================
           */

          /**
           * Get an Artist
           */
          getArtist: function (artist) {
            artist = artist.indexOf('spotify:') === -1 ? artist : artist.split(':')[2];

            return this.api('/artists/' + artist);
          },

          /**
           * Get multiple artists
           */
          getArtists: function (artists) {
            artists = angular.isString(artists) ? artists.split(',') : artists;
            angular.forEach(artists, function (value, index) {
              artists[index] = value.indexOf('spotify:') > -1 ? value.split(':')[2] : value;
            });
            return this.api('/artists/', 'GET', {
              ids: artists ? artists.toString() : ''
            });
          },

          //Artist Albums
          getArtistAlbums: function (artist, options) {
            artist = artist.indexOf('spotify:') === -1 ? artist : artist.split(':')[2];

            return this.api('/artists/' + artist + '/albums', 'GET', options);
          },

          /**
           * Get Artist Top Tracks
           * The country: an ISO 3166-1 alpha-2 country code.
           */
          getArtistTopTracks: function (artist, country) {
            artist = artist.indexOf('spotify:') === -1 ? artist : artist.split(':')[2];

            return this.api('/artists/' + artist + '/top-tracks', 'GET', {
              country: country
            });
          },

          getRelatedArtists: function (artist) {
            artist = artist.indexOf('spotify:') === -1 ? artist : artist.split(':')[2];

            return this.api('/artists/' + artist + '/related-artists');
          },


          /**
            ====================== Tracks =====================
           */
          getTrack: function (track) {
            track = track.indexOf('spotify:') === -1 ? track : track.split(':')[2];

            return this.api('/tracks/' + track);
          },

          getTracks: function (tracks) {
            tracks = angular.isString(tracks) ? tracks.split(',') : tracks;
            angular.forEach(tracks, function (value, index) {
              tracks[index] = value.indexOf('spotify:') > -1 ? value.split(':')[2] : value;
            });
            return this.api('/tracks/', 'GET', {
              ids: tracks ? tracks.toString() : ''
            });
          },


          /**
            ====================== Playlists =====================
           */
          getUserPlaylists: function (userId, options) {
            return this.api('/users/' + userId + '/playlists', 'GET', options, null, {
              'Authorization': 'Bearer ' + this.authToken
            });
          },

          getPlaylist: function (userId, playlistId, options) {
            return this.api('/users/' + userId + '/playlists/' + playlistId, 'GET', options, null, this._auth());
          },

          getPlaylistTracks: function (userId, playlistId, options) {
            return this.api('/users/' + userId + '/playlists/' + playlistId + '/tracks', 'GET', options, null, this._auth());
          },

          createPlaylist: function (userId, options) {
            return this.api('/users/' + userId + '/playlists', 'POST', null, options, this._auth(true));
          },

          addPlaylistTracks: function (userId, playlistId, tracks, options) {
            tracks = angular.isArray(tracks) ? tracks : tracks.split(',');
            angular.forEach(tracks, function (value, index) {
              tracks[index] = value.indexOf('spotify:') === -1 ? 'spotify:track:' + value : value;
            });
            return this.api('/users/' + userId + '/playlists/' + playlistId + '/tracks', 'POST', {
              uris: tracks.toString(),
              position: options ? options.position : null
            }, null, this._auth(true));
          },

          removePlaylistTracks: function (userId, playlistId, tracks) {
            tracks = angular.isArray(tracks) ? tracks : tracks.split(',');
            var track;
            angular.forEach(tracks, function (value, index) {
              track = tracks[index];
              tracks[index] = {
                uri: track.indexOf('spotify:') === -1 ? 'spotify:track:' + track : track
              };
            });
            return this.api('/users/' + userId + '/playlists/' + playlistId + '/tracks', 'DELETE', null, {
              tracks: tracks
            }, this._auth(true));
          },

          reorderPlaylistTracks: function (userId, playlistId, options) {
            return this.api('/users/' + userId + '/playlists/' + playlistId + '/tracks', 'PUT', null, options, this._auth(true));
          },

          replacePlaylistTracks: function (userId, playlistId, tracks) {
            tracks = angular.isArray(tracks) ? tracks : tracks.split(',');
            var track;
            angular.forEach(tracks, function (value, index) {
              track = tracks[index];
              tracks[index] = track.indexOf('spotify:') === -1 ? 'spotify:track:' + track : track;
            });
            return this.api('/users/' + userId + '/playlists/' + playlistId + '/tracks', 'PUT', {
              uris: tracks.toString()
            }, null, this._auth(true));
          },

          updatePlaylistDetails: function (userId, playlistId, options) {
            return this.api('/users/' + userId + '/playlists/' + playlistId, 'PUT', null, options, this._auth(true));
          },

          /**
            ====================== User =====================
           */

          getUser: function (userId) {
            return this.api('/users/' + userId);
          },

          getCurrentUser: function () {
            return this.api('/me', 'GET', null, null, this._auth());
          },

          /**
            ====================== User Library =====================
           */
          getSavedUserTracks: function (options) {
            return this.api('/me/tracks', 'GET', options, null, this._auth());
          },

          userTracksContains: function (tracks) {
            tracks = angular.isString(tracks) ? tracks.split(',') : tracks;
            angular.forEach(tracks, function (value, index) {
              tracks[index] = value.indexOf('spotify:') > -1 ? value.split(':')[2] : value;
            });
            return this.api('/me/tracks/contains', 'GET', {
              ids: tracks.toString()
            }, null, this._auth());
          },

          saveUserTracks: function (tracks) {
            tracks = angular.isString(tracks) ? tracks.split(',') : tracks;
            angular.forEach(tracks, function (value, index) {
              tracks[index] = value.indexOf('spotify:') > -1 ? value.split(':')[2] : value;
            });
            return this.api('/me/tracks', 'PUT', {
              ids: tracks.toString()
            }, null, this._auth());
          },

          removeUserTracks: function (tracks) {
            tracks = angular.isString(tracks) ? tracks.split(',') : tracks;
            angular.forEach(tracks, function (value, index) {
              tracks[index] = value.indexOf('spotify:') > -1 ? value.split(':')[2] : value;
            });
            return this.api('/me/tracks', 'DELETE', {
              ids: tracks.toString()
            }, null, this._auth(true));
          },

          /**
            ====================== Browse =====================
           */
          getFeaturedPlaylists: function (options) {
            return this.api('/browse/featured-playlists', 'GET', options, null, this._auth());
          },

          getNewReleases: function (options) {
            return this.api('/browse/new-releases', 'GET', options, null, this._auth());
          },

          getCategories: function (options) {
            return this.api('/browse/categories', 'GET', options, null, this._auth());
          },

          getCategory: function (category_id, options) {
            return this.api('/browse/categories/' + category_id, 'GET', options, null, this._auth());
          },

          getCategoryPlaylists: function (category_id, options) {
            return this.api('/browse/categories/' + category_id + '/playlists', 'GET', options, null, this._auth());
          },

          /**
            ====================== Following =====================
           */
          follow: function (type, ids) {
            return this.api('/me/following', 'PUT', { type: type, ids: ids }, null, this._auth());
          },

          unfollow: function (type, ids) {
            return this.api('/me/following', 'DELETE', { type: type, ids: ids }, null, this._auth());
          },

          userFollowingContains: function (type, ids) {
            return this.api('/me/following/contains', 'GET', { type: type, ids: ids }, null, this._auth());
          },

          followPlaylist: function (userId, playlistId, isPublic) {
            return this.api('/users/' + userId + '/playlists/' + playlistId + '/followers', 'PUT', null, {
              public: isPublic || null
            }, this._auth(true));
          },

          unfollowPlaylist: function (userId, playlistId) {
            return this.api('/users/' + userId + '/playlists/' + playlistId + '/followers', 'DELETE', null, null, this._auth());
          },

          playlistFollowingContains: function(userId, playlistId, ids) {
            return this.api('/users/' + userId + '/playlists/' + playlistId + '/followers/contains', 'GET', {
              ids: ids.toString()
            }, null, this._auth());
          },

          /**
            ====================== Login =====================
           */
          setAuthToken: function (authToken) {
            this.authToken = authToken;
            return this.authToken;
          },

          login: function () {
            var deferred = $q.defer();
            var that = this;

            var w = 400,
                h = 500,
                left = (screen.width / 2) - (w / 2),
                top = (screen.height / 2) - (h / 2);

            var params = {
              client_id: this.clientId,
              redirect_uri: this.redirectUri,
              scope: this.scope || '',
              response_type: 'token'
            };

            var authCompleted = false;
            var authWindow = openDialog(
              'https://accounts.spotify.com/authorize?' + this.toQueryString(params),
              'Spotify',
              'menubar=no,location=no,resizable=yes,scrollbars=yes,status=no,width=' + w + ',height=' + h + ',top=' + top + ',left=' + left,
              function () {
                if (!authCompleted) {
                  deferred.reject();
                }
              }
            );

            function storageChanged (e) {
              if (e.key === 'spotify-token') {
                if (authWindow) { authWindow.close(); }
                authCompleted = true;

                that.setAuthToken(e.newValue);
                $window.removeEventListener('storage', storageChanged, false);

                deferred.resolve(e.newValue);
              }
            }

            $window.addEventListener('storage', storageChanged, false);

            return deferred.promise;
          }
        };

        return new NgSpotify();
      }];

    });

}(window, angular));

控制台日志

Uncaught ReferenceError: test is not defined
  (anonymous function)  
Error: [ng:areq] http://errors.angularjs.org/1.4.7/ng/areq?p0=test&p1=not%20a%20function%2C%20got%20undefined
    at Error (native)
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js:6:416
    at qb (https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js:22:131)
    at Sa (https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js:22:218)
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js:80:81
    at O (https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js:59:501)
    at K (https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js:60:338)
    at g (https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js:54:410)
    at g (https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js:54:433)
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js:53:480
  (anonymous function)  
  (anonymous function)  
  n.$apply  
  (anonymous function)  
  e 
  d 
  zc    
  Zd    
  (anonymous function)  
  a 
  Hf.c  

1 个答案:

答案 0 :(得分:0)

模块和应用程序定义良好,但正文中的这些脚本标签是错误的部分。 Angular不适用于命令式编程。

你的身体应该使用绑定来访问控制器$ scope成员。

这样的事情:

<body ng-controller='test'>
    <div ng-repeat="artist in artists">
      {{artist|json}}
    </div>
</body>

ajax请求完成后,数据应自动显示,相反,如果发生错误,您可以在浏览器的开发者控制台中找到更多详细信息。

此外,控制器范围没有名为getAlbum的方法。

所以要解决这些问题:(假设不再需要登录工作流程)

添加一个加载相册数据的控制器方法,并从控制器本身或其他指令(如ng-click)调用它:

// inside the main controller
$scope.loadData = function () {
  Spotify.getAlbum('your album Id').then(function (data) {
    $scope.albumInfo = data;
  });
};
// call the function here or in a ng-click for instance.
$scope.loadData();

使用绑定显示数据:(在本例中为格式化为json)

<html ng-app="app">
<body ng-controller="test">
    <pre>{{albumInfo | json}}</pre>
</body>

请注意,html已经简化,您必须加载angular,main.controller和Spotify。