我正在开发一个实时地图类型的应用程序,它有一些导航按钮(例如平移,缩放等)。我添加了一个keydown事件处理程序以允许键盘控制。事件处理程序调用相同的方法。
我发现奇怪的是按钮在加载图像的响应中是活泼可靠的,但是keydown响应速度非常慢。现在,我实际上认为图像更新是由于$interval
服务重复获取它而不是来自keydown事件。注意:我已经通过为url添加日期/时间等唯一数据来处理陈旧的缓存图像(这是一个单独的问题)。
我添加了控制台日志记录,以确保imgUrl
实际上正在发生变化,确实如此。似乎按钮单击导致ngSrc使用更新的imgUrl
重新渲染,但键盘事件不是。这是一个简化的测试应用程序,它使用按钮和't'键重新创建相同的行为,在这种情况下,它们是keydown事件:
的javascript
var myApp = angular.module("myApp", ['ngMaterial'])
.controller("myCtrl", function ($scope)
{
$scope.isToggled = false;
$scope.Toggle = function ()
{
console.log("Toggle(Start): " + $scope.imgUrl);
if ($scope.isToggled)
{
$scope.imgUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Grassland_wiki.jpg/640px-Grassland_wiki.jpg";
}
else
{
$scope.imgUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Monotropa_uniflora_03769.jpg/640px-Monotropa_uniflora_03769.jpg";
}
$scope.isToggled = !$scope.isToggled;
console.log("Toggle(End): " + $scope.imgUrl);
};
$scope.ProcessKey = function (e)
{
if (e.key === "t")
{
$scope.Toggle();
}
};
$scope.Toggle();
document.addEventListener("keydown", $scope.ProcessKey);
});
HTML
<div ng-controller="myCtrl" ng-app="myApp">
<md-button class="md-raised" ng-click="Toggle()">Toggle</md-button>
<img id="testImg" ng-cloak ng-src="{{imgUrl}}">
</div>
我在javascript和angularjs中遇到了支持C#应用程序的问题,这是我的大部分经验。
我不确定根本原因是什么。也许这与引用$scope
函数变量/表达式的javascript事件监听器有关?部分依赖是在我的主应用程序中,我使用$http
服务来获取图像。
我有这样的替代方式吗?有没有办法强迫图像重新渲染?
答案 0 :(得分:2)
因为您在AngularJS
之外添加了一个事件,所以Angular永远不会知道$scope
属性已更改。所以你手动告诉Angular使用$scope.$apply()
改变了一些东西。
var myApp = angular.module("myApp", [])
.controller("myCtrl", function ($scope)
{
$scope.isToggled = false;
$scope.Toggle = function ()
{
console.log("Toggle(Start): " + $scope.imgUrl);
if ($scope.isToggled)
{
$scope.imgUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Grassland_wiki.jpg/640px-Grassland_wiki.jpg";
}
else
{
$scope.imgUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Monotropa_uniflora_03769.jpg/640px-Monotropa_uniflora_03769.jpg";
}
$scope.isToggled = !$scope.isToggled;
console.log("Toggle(End): " + $scope.imgUrl);
};
$scope.ProcessKey = function (e)
{
if (e.key === "t")
{
$scope.Toggle();
$scope.$apply();
}
};
$scope.Toggle();
document.addEventListener("keydown", $scope.ProcessKey);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="myCtrl" ng-app="myApp">
<button class="md-raised" ng-click="Toggle()">Toggle</button>
<img id="testImg" ng-cloak ng-src="{{imgUrl}}">
</div>
答案 1 :(得分:1)
您可以使用$scope.apply(handler)
$scope.apply(function () {
// Angular is now aware that something might of changed
$scope.changeThisForMe = true;
});
答案 2 :(得分:0)
注意:我更喜欢$scope.apply();
解决方案,因为它们不需要首先关注网站元素。
因为我很顽固,所以我找到了另一种解决方案,其目标是留在AngularJS,并认为我会提供完整性。
基于以下帖子: AngularJS ng-keydown directive only working for <input> context?
我从javascript中删除了以下行:
document.addEventListener("keydown", $scope.ProcessKey);
我使用ng-keydown
对html进行了以下调整,之前我只能使用输入标记。我添加了tabindex
,它允许项目处于焦点并解决输入标签问题:
<div ng-controller="myCtrl" ng-app="myApp" tabindex="0" ng-keydown="ProcessKey($event);">
<md-button class="md-raised" ng-click="Toggle()">Toggle</md-button><br>
<img id="testImg" ng-cloak ng-src="{{imgUrl}}">
</div>
请注意,我无法让它在body标签上工作。