单击、ng-class 和 $digest 循环的执行顺序

Order of execution of on-click, ng-class & $digest cycles

我有一个 ui-view,可以在 3 个不同的模板之间切换。不过,其中一项要求ui是模板从左侧或右侧滑入和滑出,具体取决于在每个模板中单击的 link。

现在我面临的问题大致如下:

<div ui-view class='list' ng-class="{'slide-left':myCon.direction=='left','slide-right:myCon.direction=='right'}">
    <a ng-click="myCon.setDirectionAndGoToState('right')">slide Right</a>
    <a ng-click="myCon.setDirectionAndGoToState('left')">slide Left</a>
</div>

我通过 Chrome 的开发人员工具在 DOM 中看到的是,当点击发生在 "slide Right" link 上时,ui-视图元素(离开的和新生成的进入的)得到正确的 .slide-right classes。 然后离开的 ui-view 元素消失,活动的 ui-view 元素有 class of .slide-right。 现在,如果我然后单击 "Slide Left" link,则离开的 ui-视图应用了 .slide-left class,但新生成的进入 ui-view 仍然应用了 .slide-right class...大概是从它被复制的时候开始...因此这意味着 $state.go 的复制是在由ng-click 事件实际上发生在 ng-class 之前。或者至少这是我得到的暗示....

有没有人知道这是否是实际发生的事情...如果是,我有没有办法更改顺序以便在新的之后评估 ng-class direction 在控制器中设置,$state.go 只执行它的复制 after?

谢谢!

您没有包含 setDirectionAndGoToState() 函数的内容,但如果您想做的只是控制操作的顺序,那么这很容易做到。请记住 Javascript 是单线程的。 AngularJS "digest" 机制 运行 在每个事件处理周期的最后,这就是你的 ng-class 表达式之类的东西将被评估的地方。如果像 $state.go(...) 这样的事情对你来说执行得太早,只需将它们移到 "next tick"。这是常用的技巧:

$scope.setDirectionAndGoToState = function(direction) {
    $scope.direction = direction;
    $timeout(function() {
        $state.go('newstate');
    }, 0);
};

以这种方式调用超时将推迟执行里面的代码,直到"next tick" - 在摘要循环有运行之后。这将使 classes 在转换到新状态之前得到应用。您显然可以混合和匹配使用此机制(甚至嵌套它们)来精确控制排序。

请注意,虽然这对于状态转换等偶尔发生的事件来说很好,但它确实会引入轻微的延迟 - 回调永远不会是零毫秒。我不建议将它用于 window-resize 事件处理程序之类的东西 - 对于这些情况还有其他技巧。