我有一个声音云的自定义指令,需要soundcloud网址。 soundcloud url是通过$ http服务从数据库中获取的,但是,加载了soundcloud自定义指令的div,并且在它被定义之前需要soundcloud url的值。
我得到的Plangular指令代码在这里: https://github.com/jxnblk/plangular/blob/master/src/plangular.js *我没有发展这个
这是我的HTML代码:
<div plangular="{{soundcloud}}">
<button ng-click="playPause()">Play/Pause</button>
<progress ng-value="currentTime / duration || 0">
{{ currentTime / duration || 0 }}
</progress>
</div>
这是Angular Code:
displaySong.controller('song', ['$scope', '$http', 'fetchSong', function($scope, $http, fetchSong) {
$scope.songID
$scope.songName;
//Controller properties
$scope.songPromise; //The song promise for fetching
$scope.init = function(songID, userID) {
$scope.songID = songID;
$scope.userID = userID;
$scope.songPromise = $http({
method: "post",
url: fetchSong,
data: {
song_id: $scope.songID
},
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(function(successResponse) {
console.log('Successfully fetched song');
console.log(successResponse);
var song = successResponse.data;
$scope.songID = song.song_id;
$scope.songName = song.song_name;
$scope.songType = song.song_type;
$scope.songEmbed = song.song_embed;
$scope.soundcloud = song.song_embed;
}, function(errorResponse) {
console.log('Error fetching');
$scope.songID = null;
});
};
}]);
我知道这是异步性质的问题,因为当我在歌曲控制器的开头添加这一行时:
$scope.soundcloud = "https://soundcloud.com/jshigley/shine";
它完美无缺。我还注意到,当我向指令提出的播放/暂停按钮发送垃圾邮件时,我收到了多个控制台错误,其中包括#404; HTTP 404 Not Found&#34;这让我相信它&#39; ; s试图找到未定义网址的跟踪
因为它是一个div指令而不是一个函数调用,所以我不能使用promises,比如将一个然后链接到我的$ scope.songPromise。我已经想过将它放入控制器并让控制器执行类似$ timeout的操作5秒,但我认为这不会延迟DOM的执行。
soundcloud URL最终会被加载,但在plangular指令的眼中它仍未定义(我实际上遇到了很多这些问题,加载范围和指令的时机不正确)。任何Angular Wizards都愿意教我如何驯服AngularJS的异步性质?
答案 0 :(得分:2)
您可以在custom指令中使用$ watch来监视更改url属性的时间。 在
link: function(scope, el, attr) {
从
改变if (src) {
resolve({ url: src, client_id: client_id }, function(err, res) {
if (err) { console.error(err); }
scope.$apply(function() {
scope.track = createSrc(res);
if (Array.isArray(res)) {
scope.tracks = res.map(function(track) {
return createSrc(track);
});
} else if (res.tracks) {
scope.playlist = res;
scope.tracks = res.tracks.map(function(track) {
return createSrc(track);
});
}
});
});
}
到
scope.$watch('attr.plangular', function(newVal) {
resolve({ url: attr.plangular, client_id: client_id }, function(err, res) {
if (err) { console.error(err); }
scope.$apply(function() {
scope.track = createSrc(res);
if (Array.isArray(res)) {
scope.tracks = res.map(function(track) {
return createSrc(track);
});
} else if (res.tracks) {
scope.playlist = res;
scope.tracks = res.tracks.map(function(track) {
return createSrc(track);
});
}
});
});
}, true);
如果您不想更改指令,那么您可能希望仅在获取网址时使用ng-if加载该plangular div。
<div plangular="{{soundcloud}}" ng-if="haveurl">
并在角度代码中:
}).then(function(successResponse) {
console.log('Successfully fetched song');
console.log(successResponse);
$scope.haveurl = true;
答案 1 :(得分:0)
尝试使用此类ng-show
仅在您的$ http请求完成后显示div
。
<div ng-show="httpRequestComplete" plangular="{{soundcloud}}">
<button ng-click="playPause()">Play/Pause</button>
<progress ng-value="currentTime / duration || 0">
{{ currentTime / duration || 0 }}
</progress>
</div>
displaySong.controller('song', ['$scope', '$q', '$http', 'fetchSong', function($scope, $http, fetchSong) {
/* add $q promise library */
$scope.songID
$scope.songName;
var httpRequest = function() {
var deferred = $q.defer();
$http({
method: "post",
url: fetchSong,
data: {
song_id: $scope.songID
},
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function(successResponse) {
deferred.resolve({response: successResponse});
console.log('Successfully fetched song', successResponse);
var song = successResponse.data;
$scope.songID = song.song_id;
$scope.songName = song.song_name;
$scope.songType = song.song_type;
$scope.songEmbed = song.song_embed;
$scope.soundcloud = song.song_embed;
}).error(function(error) {
console.log(error);
});
return deferred.promise;
};
httpRequest().then(function(response) {
$scope.httpRequestComplete = true;
console.log('div will show');
};
}]);
我会做这样的事情,将div
的显示延迟到httpRequestComplete = true
,或直到你的承诺($ q)完成。这样做可确保在您获得相关信息之前,div
尚未加载。