在AngularJS中更新没有作用域的变量.$apply()
Update variable without scope.$apply() in AngularJS
在我的项目中,画布元素显示了一个操纵杆。通过鼠标/触摸事件,画布被更新为看起来像用户在移动操纵杆。这很好。坐标保存在一个对象中,如下所示:
scope.point = {
x: 0,
y: 0,
};
我添加了这个HTML来显示给用户:
<span>X:{{point.x.toFixed(2)}} Y:{{point.y.toFixed(2)}}</span>
问题是,当scope.point.x和scope.point.y的值被改变时(在鼠标/触摸事件处理程序中),它们不会在HTML中得到更新。唯一的解决方案似乎是添加:
scope.$apply()
//or
scope.$digest()
到渲染循环。这确实有效,但看起来不太优雅(恕我冒昧),并且使性能明显下降,正如预期的那样。
还有其他解决方案吗?
提前感谢。
PS:虽然我不认为这是相关的,参考这是事件处理程序代码,和渲染循环: //handles mouse or touch movement on joystick
scope.mouseMove = function(evt) {
if (leftClick == 1) { //check if left mouse button down or touch
// get cursor or touch coordinates, saved in point object.
if (evt.type == 'touchstart' || evt.type == 'touchmove') {
scope.point.x = evt.targetTouches[0].pageX - joystick.offsetLeft;
scope.point.y = evt.targetTouches[0].pageY - joystick.offsetTop;
} else {
scope.point.x = evt.pageX - joystick.offsetLeft - 3;
scope.point.y = evt.pageY - joystick.offsetTop - 3;
};
//make coordinates relative to canvas center
scope.point = GeometrySrv.centerCoord(scope.point, joystick);
//if Directional Lock is ON, enforce
if (scope.lockMode != "fullAnalog") {
scope.point = GeometrySrv.forceDirectionLock(scope.point.x, scope.point.y, scope.lockMode);
};
// force coordinates into maxRadius
if (!GeometrySrv.isInsideCircle(scope.point.x, scope.point.y, maxRadius)) {
scope.point = GeometrySrv.forceIntoCircle(scope.point.x, scope.point.y, maxRadius);
};
//send coordinates back to server (websocket)
updateJoystick(scope.point, scope.lockMode);
};
};
function renderLoop() {
//erases previous joystick position
resetJoystick();
// erases previous vector
resetVector();
//change coordinates to canvas reference
scope.point = GeometrySrv.canvasCoord(scope.point, joystick);
DrawSrv.drawLineFromCenter(joystickctx, scope.point.x, scope.point.y);
if (scope.showVector) {
DrawSrv.drawLineFromCenter(vectorctx, scope.point.x * vector.width / joystick.width, scope.point.y * vector.width / joystick.width);
};
//redraw joystick position
DrawSrv.drawCircle(joystickctx, scope.point.x, scope.point.y, radius, maxRadiusBGColor);
//change back to relative coordinates
scope.point = GeometrySrv.centerCoord(scope.point, joystick);
//scope.$digest();
//call renderLoop every 15ms (60fps)
renderReq = requestAnimationFrame(renderLoop);
};
我将创建一个过滤器,这样您仍然可以绑定到对象,但是您的过滤器以特定的方式显示对象。
[your angular module].filter('toFixed', [function () {
return function (input) {
if (typeof input.toFixed == 'function')
return input.toFixed(2);
return input;
};
}]);
然后绑定到HTML:
<span>X:{{point.x | toFixed}} Y:{{point.y | toFixed}}</span>
$apply
在内部调用$rootScope.$digest
,因此在本地范围内使用$diggest
以获得更好的性能。为了获得最佳性能,放弃数据绑定并直接操作DOM。你可以在自己的angular指令中完成。
了解$applyAsync() -它允许您将$digest()周期排队并大约每10ms节流一次。
它也足够聪明,可以知道Angular是否已经在$digest()循环中,从而避免了在$digest()完成之前调用$apply()两次的恼人错误。
相关文章:
- 将函数的上下文应用于javascript变量
- 无法导出函数expressjs/requestjs中的变量
- 函数参数中的数据与指定变量之间的任何性能差异
- 将PHP变量传递给jQuery时遇到问题
- 如何通过ajax刷新JSF填充的javascript变量
- 参数变量出现ngTable指令问题
- 通过javascript重定向html传递php变量
- 将jsp文件下拉列表中的选定项分配给一个java变量(比如String selection)
- 全局变量和全局对象的属性之间有什么区别吗
- 如何在Bootstrap Modal中为动态点击生成的变量设置jade属性
- 值对象在某个变量发生更改后发生更改
- Javascript变量赋值|
- AngularJS-在JSON选择器中使用变量名
- $apply在angularJs中没有更新我的范围变量
- 角度变量未更新,尝试调用$apply导致“;摘要已经在进行中”;错误
- 使Math.max.apply读变量
- 如何使用闭包的apply/call通过嵌套对象传递变量
- 在angular 1.4.4中,为什么作用域变量的变化不需要$watch或$apply就能传播到DOM ?
- 在AngularJS中更新没有作用域的变量.$apply()
- Javascript .apply带有变量函数名