UI 路由器 - 状态转换延迟(非常慢)
UI Router - State transition delay (very slow)
我在 angular 应用程序中使用 ui-router
,在大多数情况下它都没有问题。
在某些情况下 $state.go("my-state")
不会触发立即转换。有时它非常慢(几秒钟后过渡到 "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()
}
)
}
// [...]
我是不是漏掉了什么?
我可以对 "force" ui-router 做些什么来开始转换吗?
那是因为 element
的 'on'
事件在 angular 的摘要循环之外。
像这样更新需要重定向的代码:
else if(user.level == "member") {
scope.$apply(function() {
$('#elementId').remove()
// PROBLEM HERE:
$state.go("my-state")
});
}
scope.$apply
专门用于像这种需要手动调用angular摘要循环的情况。
还有一件事。
如果发生错误说 "digest loop is already in progress" 您可以将此技术与 $timeout
:
一起使用
else if(user.level == "member") {
$timeout(function() {
$('#elementId').remove()
// PROBLEM HERE:
$state.go("my-state")
});
}
但请记住,以这种方式使用 $timeout
被视为一种 hack,最好找到绕过它的方法,但它仍然被广泛使用。
P.S. 不要忘记包含 $timeout
作为指令定义函数的依赖项。
如果模板中的 ng-repeat 列表很大,切换路由会出现一个有趣的问题。可以延迟加载新视图。在我的例子中,它长达 7 秒!我找到的一个解决方案是在切换视图之前先删除列表中的 HTML 节点。这样 UI 路由器就不会卸载繁重的 HTML 页面。在这个例子中,clinicList 是一个长列表的父节点。
var clinicList = document.getElementById('clinicList');
if (clinicList) document.getElementById('clinicList').innerHTML = '';
$state.go('selectshiftlistview');
我在 angular 应用程序中使用 ui-router
,在大多数情况下它都没有问题。
在某些情况下 $state.go("my-state")
不会触发立即转换。有时它非常慢(几秒钟后过渡到 "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()
}
)
}
// [...]
我是不是漏掉了什么?
我可以对 "force" ui-router 做些什么来开始转换吗?
那是因为 element
的 'on'
事件在 angular 的摘要循环之外。
像这样更新需要重定向的代码:
else if(user.level == "member") {
scope.$apply(function() {
$('#elementId').remove()
// PROBLEM HERE:
$state.go("my-state")
});
}
scope.$apply
专门用于像这种需要手动调用angular摘要循环的情况。
还有一件事。
如果发生错误说 "digest loop is already in progress" 您可以将此技术与 $timeout
:
else if(user.level == "member") {
$timeout(function() {
$('#elementId').remove()
// PROBLEM HERE:
$state.go("my-state")
});
}
但请记住,以这种方式使用 $timeout
被视为一种 hack,最好找到绕过它的方法,但它仍然被广泛使用。
P.S. 不要忘记包含 $timeout
作为指令定义函数的依赖项。
如果模板中的 ng-repeat 列表很大,切换路由会出现一个有趣的问题。可以延迟加载新视图。在我的例子中,它长达 7 秒!我找到的一个解决方案是在切换视图之前先删除列表中的 HTML 节点。这样 UI 路由器就不会卸载繁重的 HTML 页面。在这个例子中,clinicList 是一个长列表的父节点。
var clinicList = document.getElementById('clinicList');
if (clinicList) document.getElementById('clinicList').innerHTML = '';
$state.go('selectshiftlistview');