控制器未定义

Controller is undefined

本文关键字:未定义 控制器      更新时间:2023-09-26

提前感谢您的帮助。我是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);
    });
  }]);

angular-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  

模块和应用程序都定义得很好,但是正文中的这些脚本标记是错误的部分。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。