Angularjs ng show指令在触发后更新dom花费的时间太长

Angularjs ng show指令在触发后更新dom花费的时间太长,angularjs,delay,directive,ng-show,Angularjs,Delay,Directive,Ng Show,该应用程序有一个控制器,使用服务创建视频播放器实例。视频播放器每隔几秒钟触发事件以显示进度。当视频到达某个点时,我想在视频播放器顶部显示一个小部件 视图将小部件包装在ng show指令中 触发事件并填充值后,dom元素需要60秒以上的时间才能接收到删除ng hide类的信号 如果我尝试使用普通的dom方法(如document.getElementById(eleId).innerHTML=newHTML)实现此功能,那么更新是即时的 我做错了什么?以下是代码中的完整序列: 控制器: MyApp.

该应用程序有一个控制器,使用服务创建视频播放器实例。视频播放器每隔几秒钟触发事件以显示进度。当视频到达某个点时,我想在视频播放器顶部显示一个小部件

视图将小部件包装在ng show指令中

触发事件并填充值后,dom元素需要60秒以上的时间才能接收到删除ng hide类的信号

如果我尝试使用普通的dom方法(如document.getElementById(eleId).innerHTML=newHTML)实现此功能,那么更新是即时的

我做错了什么?以下是代码中的完整序列:

控制器:

MyApp.controller('SectionController', ['$scope', 'PlayerService'], function($scope, PlayerService){
$scope.createPlayer = function() {
    PlayerService.createPlayer($scope, wrapperId);
}});
服务:

MyApp.service('PlayerService', [], function(){

this.createPlayer=function(controllerScope, playerWrapper){

    PLAYER_SCRIPT.create(playerWrapper) {

        wrapper : playerWrapper,
        otherParam : value,
        onCreate : function(player) {

            player.subscribe(PLAY_TIME_CHANGE, function(duration){
                showWidget(controllerScope, duration);
            })

        }
    }

}

function showWidget(controllerScope, duration) {
    if(duration>CERTAIN_TIME) {
        $rootScope.widgetData = {some:data}
        $rootScope.showWidget = true;
    }

}});
视图:

{{widgetData.stuff}

隐藏视图中是否有复杂的角度信息

您应该尝试使用
ngif
而不是
ngshow
,区别在于,当条件为false时,
ngif
将从DOM中删除元素,而不是仅仅隐藏它(这也是您在vanilla JS中所做的)


但是,当使用
ng show
简单地隐藏视图时,视图中的所有观察者和绑定都将继续由Angular计算。如果
ng如果
解决了您的问题,请告诉我们,否则我将编辑我的答案。

您的隐藏视图中是否有复杂的角度信息

您应该尝试使用
ngif
而不是
ngshow
,区别在于,当条件为false时,
ngif
将从DOM中删除元素,而不是仅仅隐藏它(这也是您在vanilla JS中所做的)

但是,当使用
ng show
简单地隐藏视图时,视图中的所有观察者和绑定都将继续由Angular计算。如果
ng如果
解决了您的问题,请告诉我们,否则我将编辑我的答案。

解决了它$作用域。$apply()成功了

我的猜测是,由于应用程序内部的其他复杂逻辑广告绑定,以默认方式计算更改时出现了延迟

@floribon感谢你对“复杂棱角的东西”的微妙暗示

服务功能中的代码更改为:

function showWidget(controllerScope, duration) {
if(duration>CERTAIN_TIME) {
    $rootScope.widgetData = {some:data}
    $rootScope.showWidget = true;
    $rootScope.$apply();
}}
解决了$作用域。$apply()成功了

我的猜测是,由于应用程序内部的其他复杂逻辑广告绑定,以默认方式计算更改时出现了延迟

@floribon感谢你对“复杂棱角的东西”的微妙暗示

服务功能中的代码更改为:

function showWidget(controllerScope, duration) {
if(duration>CERTAIN_TIME) {
    $rootScope.widgetData = {some:data}
    $rootScope.showWidget = true;
    $rootScope.$apply();
}}

刚刚试过ng if。对延迟没有影响。显示dom元素仍然需要60秒的时间。是的,我的应用程序中还有很多其他复杂的东西。正在为玩家捕获其他事件。请尝试ng if。对延迟没有影响。显示dom元素仍然需要60秒的时间。是的,我的应用程序中还有很多其他复杂的东西。还有其他一些事件正在为玩家捕获。很好,你发现了。仅供参考,这意味着没有需要一段时间的“巨大计算”。发生的情况很可能是您在60年代后通过单击、输入或刷新视图的任何操作触发了Diget循环。每次从角度堆栈中更新$scope时,即每次异步函数(如
setTiemout
或自定义服务器调用)之后,都需要手动触发摘要周期(
$scope.$apply
)。请注意,
$timeout
$http
是异步的,但在最后会有一个隐式应用。@floribon,感谢您解释这个行为。范围更新发生在视频播放器进度事件回调中。角度范围已传递给回调。所以,我猜我们可以考虑更新“角度堆栈”,正如你提到的。很好,你发现了。仅供参考,这意味着没有需要一段时间的“巨大计算”。发生的情况很可能是您在60年代后通过单击、输入或刷新视图的任何操作触发了Diget循环。每次从角度堆栈中更新$scope时,即每次异步函数(如
setTiemout
或自定义服务器调用)之后,都需要手动触发摘要周期(
$scope.$apply
)。请注意,
$timeout
$http
是异步的,但在最后会有一个隐式应用。@floribon,感谢您解释这个行为。范围更新发生在视频播放器进度事件回调中。角度范围已传递给回调。所以,我猜我们可以考虑更新“角度堆栈”,正如你提到的。