gpt4 book ai didi

AngularJS 从一个服务广播不会触发对第二个服务的调用

转载 作者:行者123 更新时间:2023-12-02 23:27:56 24 4
gpt4 key购买 nike

我定义了两个 AngularJS 服务...一个用于 YouTube 播放器 API,另一个用于 YouTube iFrame 数据 API。它们看起来像这样:

angular.module('myApp.services',[]).run(function() {
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
})
.factory('YtPlayerApi', ['$window', '$rootScope', function ($window, $rootScope) {
var ytplayer = {"playerId":null,
"playerObj":null,
"videoId":null,
"height":390,
"width":640};

$window.onYouTubeIframeAPIReady = function () {
$rootScope.$broadcast('loadedApi');
};

ytplayer.setPlayerId = function(elemId) {
this.playerId=elemId;
};

ytplayer.loadPlayer = function () {
this.playerObj = new YT.Player(this.playerId, {
height: this.height,
width: this.width,
videoId: this.videoId
});
};
return ytplayer;
}])
.factory('YtDataApi', ['appConfig','$http', function(cfg,$http){
var _params = {
key: cfg.youtubeKey
};
var api="https://www.googleapis.com/youtube/v3/";
var yt_resource = {"api":api};
yt_resource.search = function(query, parameters) {
var config = {
params: angular.extend(angular.copy(_params),
{maxResults: 10,
part: "snippet"}, parameters)
};
return $http.get(api + "search?q=" + query, config);
};
return yt_resource;
}]);

(另请注意,我的播放器服务的“setPlayerId”函数是由自定义指令调用的......但这对我的问题并不重要)。

所以,问题来了。我需要确保在设置视频 ID 并创建播放器之前加载播放器 API 代码,这就是我让它广播“loadedApi”消息的原因。如果我在 Controller 中传递一个硬编码的视频 ID,这效果很好,如下所示:

function ReceiverCtrl($scope,$rootScope,$routeParams,ytplayer,ytdataapi) {
$scope.$on('loadedApi',function () {
ytplayer.videoId='voNEBqRZmBc';
ytplayer.loadPlayer();
});
}

但是,在我使用数据 API 服务进行 API 调用之前,我的视频 ID 不会被确定,因此我还必须确保该调用的结果已返回。这就是我遇到问题的地方......如果我这样做:

      $scope.$on('loadedApi',function () {
ytdataapi.search("Mad Men", {'topicId':$routeParams.topicId,
'type':'video',
'order':'viewCount'})
.success(function(apiresults) { // <-- this never gets triggered
console.log(apiresults); // <-- likewise, this obviously doesn't either
});
});

然后,由于某种原因,与数据服务的交互永远不会发生。我知道数据服务工作得很好,因为当我从 $on 语句中取消嵌套它时,它会返回 api 结果。但有时延迟会导致结果返回的速度不够快,无法在播放器服务中使用它们。关于在收到播放器 API 已准备就绪的消息后我可以做什么来进行数据搜索的任何想法,但仍然将这两个服务保留为两个单独的服务(因为其他 Controller 只使用其中之一,所以我不希望它们在服务级别上相互依赖)?

最佳答案

想通了;我必须调用 $scope.$apply(),如下所示:

function ReceiverCtrl($scope,$rootScope,$routeParams,ytplayer,ytdataapi) {
$scope.$on('loadedApi',function () {
ytdataapi.search("",{'topicId':$routeParams.topicId,'type':'video','maxResults':1,'order':'viewCount'}).success(function(apiresults) {
ytplayer.videoId=apiresults.items[0].id.videoId;
ytplayer.loadPlayer();
});
$scope.$apply();
});
}

有没有人可以解释为什么它会起作用? $scope.$digest() 也可以工作......但我认为这些方法仅在您需要更新绑定(bind)时使用,因为 Angular 不知道一些 javascript 代码。我这里的嵌套是否可以这样做(我认为不应该这样做,因为我的 ytdataapi 服务正在使用 $http)?

关于AngularJS 从一个服务广播不会触发对第二个服务的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18282527/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com