UI路由器-状态转换延迟(非常慢)

UI Router - State transition delay (very slow)

本文关键字:非常 延迟 转换 路由器 状态 UI      更新时间:2023-09-26

我在角度应用程序中使用ui-router,在绝大多数情况下,它都能正常工作。

有一种情况很困难,$state.go("my-state")不会立即触发转换。有时它只是非常慢(几秒钟后转换到"我的状态"),有时直到我移动鼠标一段时间并启动一些事件处理程序(绝对与启动转换的事件处理程序无关),它才会启动。

这就是我指令中的内容:

// [...]
link: funtcion(scope, elm, attrs){
    elm.on('mouseenter', function(){
            // ...
        })
        .on('mousemove', function($event){
            // ...
        })
        .on('mouseleave', function(){
            // ...
        })
        .on('change', function(){
            // ...
        })
        .on('click', (e) ->
            if(someCondition){
                e.preventDefault()
                e.stopImmediatePropagation()
                e.stopPropagation()
                if(user.level == "visitor"){
                    $rootScope.$broadcast('showLogin')
                }
                else if(user.level == "member") 
                    $('#elementId').remove()
                    // PROBLEM HERE:
                    $state.go("my-state")
            }
            else if(anotherCondition){
                $('#elementId').remove()
            } 
        )
}
// [...]

我是不是错过了什么
我能做些什么来"强迫"ui路由器开始转换吗?

这是因为element'on'事件在angular的摘要循环之外。在需要重定向的地方更新代码,如下所示:

else if(user.level == "member") {
    scope.$apply(function() {
        $('#elementId').remove()
        // PROBLEM HERE: 
        $state.go("my-state")
    });
}

scope.$apply专门用于像这样需要手动调用angular的摘要循环的情况。

不过还有一件事。如果出现"摘要循环已经在进行中"的错误,您可以将此技术与$timeout:一起使用

else if(user.level == "member") {
    $timeout(function() {
        $('#elementId').remove()
        // PROBLEM HERE: 
        $state.go("my-state")
    });
}

但请记住,以这种方式使用$timeout被认为是一种黑客攻击,最好能找到绕过它的方法,但它仍然被广泛使用。

p.S.不要忘记将$timeout作为指令定义函数的依赖项。

p.p.S.阅读更多关于摘要循环的信息

如果模板中有大的ng重复列表,那么切换路由会出现一个有趣的问题。加载新视图可能会延迟。在我的情况下,它长达7秒!我找到的一个解决方案是在切换视图之前先删除列表中的HTML节点。通过这种方式,UI路由器不会卸载沉重的HTML页面。在本例中,clinicList是长列表的父节点。

var clinicList = document.getElementById('clinicList');
if (clinicList) document.getElementById('clinicList').innerHTML = '';
$state.go('selectshiftlistview');