AngularJS 如何在 setTimeout 后强制更新 DOM
AngularJS How to force DOM update after setTimeout
下面的代码块等待超时,然后执行带有承诺的 HTTP 请求,然后根据响应更改 Angular Material 范围变量。在输入字段上使用 ng-change
调用它。我的 HTML 中也有一个带有 ng-hide="showStuff"
的元素,显然,当 $scope.showStuff
变为 false 时,我希望它立即消失。不幸的是,它实际上并没有消失,直到我 select 在 DOM.
中的其他内容
我之前使用 promises 来更改 DOM 中的内容,并且效果很好。为什么 DOM 不自行更新,我该如何解决?
$scope.checkSomething = function() {
// Use a timeout to prevent a checks from going off too rapidly
if (queryTimeout) {
clearTimeout(queryTimeout);
}
queryTimeout = setTimeout(function() {
bluebird.bind({}).then(function() {
return makeHttpRequest();
}).then(function(res) {
$scope.showStuff = res.data.length > 0;
})
}, 500);
}
AngularJs 的变化检测(称为 "digest cycle")不知道 运行,除非代码开始在 angular 上下文中执行。所以异步的东西不能很好地工作。这就是为什么 angular 提供诸如 $timeout、$interval 和 $q 之类的服务来执行异步操作,从而为您处理摘要周期的启动。使用那些,这种问题将非常罕见。
如果您想使用 $q 以外的其他类型的承诺,您需要手动启动摘要循环。如果您希望它很快发生,您可以使用 $scope.$apply() if you want it to happen immediately, or $scope.$applyAsync 来执行此操作,但不是同步的(如果您可能有多个调用它并且您希望它们一起批处理时很有用)。
所以如果你不想使用 $timeout 和 $q,你必须这样做:
setTimeout(function() {
bluebird.bind({}).then(function() {
return makeHttpRequest();
}).then(function(res) {
$scope.showStuff = res.data.length > 0;
$scope.$apply();
})
}, 500);
使用 $timeout
服务,它 returns 一个与 AngularJS 执行上下文及其摘要周期集成的承诺:
$scope.checkSomething = function() {
// Use a timeout to prevent a checks from going off too rapidly
if (queryTimeout) {
$timeout.cancel(queryTimeout);
}
queryTimeout = $timeout(function() {
return makeHttpRequest();
}, 500);
queryTimeout.then(function(res) {
$scope.showStuff = res.data.length > 0;
})
}
这将使 makeHttpRequest
的执行延迟 500 毫秒。 $timeout 服务 returns 用于解析来自服务器的数据的承诺。
AngularJS 通过提供自己的事件处理循环来修改正常的 JavaScript 流程。这将 JavaScript 分为经典和 AngularJS 执行上下文。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性 监视等
通过使用 AngularJS $超时服务,包装的 setTimeout
将在 AngularJS 执行上下文中执行。
有关详细信息,请参阅
下面的代码块等待超时,然后执行带有承诺的 HTTP 请求,然后根据响应更改 Angular Material 范围变量。在输入字段上使用 ng-change
调用它。我的 HTML 中也有一个带有 ng-hide="showStuff"
的元素,显然,当 $scope.showStuff
变为 false 时,我希望它立即消失。不幸的是,它实际上并没有消失,直到我 select 在 DOM.
我之前使用 promises 来更改 DOM 中的内容,并且效果很好。为什么 DOM 不自行更新,我该如何解决?
$scope.checkSomething = function() {
// Use a timeout to prevent a checks from going off too rapidly
if (queryTimeout) {
clearTimeout(queryTimeout);
}
queryTimeout = setTimeout(function() {
bluebird.bind({}).then(function() {
return makeHttpRequest();
}).then(function(res) {
$scope.showStuff = res.data.length > 0;
})
}, 500);
}
AngularJs 的变化检测(称为 "digest cycle")不知道 运行,除非代码开始在 angular 上下文中执行。所以异步的东西不能很好地工作。这就是为什么 angular 提供诸如 $timeout、$interval 和 $q 之类的服务来执行异步操作,从而为您处理摘要周期的启动。使用那些,这种问题将非常罕见。
如果您想使用 $q 以外的其他类型的承诺,您需要手动启动摘要循环。如果您希望它很快发生,您可以使用 $scope.$apply() if you want it to happen immediately, or $scope.$applyAsync 来执行此操作,但不是同步的(如果您可能有多个调用它并且您希望它们一起批处理时很有用)。
所以如果你不想使用 $timeout 和 $q,你必须这样做:
setTimeout(function() {
bluebird.bind({}).then(function() {
return makeHttpRequest();
}).then(function(res) {
$scope.showStuff = res.data.length > 0;
$scope.$apply();
})
}, 500);
使用 $timeout
服务,它 returns 一个与 AngularJS 执行上下文及其摘要周期集成的承诺:
$scope.checkSomething = function() {
// Use a timeout to prevent a checks from going off too rapidly
if (queryTimeout) {
$timeout.cancel(queryTimeout);
}
queryTimeout = $timeout(function() {
return makeHttpRequest();
}, 500);
queryTimeout.then(function(res) {
$scope.showStuff = res.data.length > 0;
})
}
这将使 makeHttpRequest
的执行延迟 500 毫秒。 $timeout 服务 returns 用于解析来自服务器的数据的承诺。
AngularJS 通过提供自己的事件处理循环来修改正常的 JavaScript 流程。这将 JavaScript 分为经典和 AngularJS 执行上下文。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性 监视等
通过使用 AngularJS $超时服务,包装的 setTimeout
将在 AngularJS 执行上下文中执行。
有关详细信息,请参阅