提前感谢您的帮助。我是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
答案 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。