角度变量未绑定到视图
Posted
技术标签:
【中文标题】角度变量未绑定到视图【英文标题】:Angular variable not binding to view 【发布时间】:2015-12-31 09:46:29 【问题描述】:我有一个 Angular/Onsen 应用程序,该应用程序的图像被放入 html5 canvas tag,我正在选择我在 hover
上的像素颜色。
视图很简单:
<ons-template id="live.html">
<ons-page ng-controller="LiveController">
<ons-toolbar>
<div class="left">
<ons-toolbar-button ng-click="menu.toggle()">
<ons-icon icon="ion-navicon" size="28px" fixed-></ons-icon>
</ons-toolbar-button>
</div>
<div class="center">Live Camera</div>
</ons-toolbar>
<canvas id="canvas" ></canvas>
<p>#hex</p>
</ons-page>
</ons-template>
您可以看到<p>
标记应该显示$scope.hex
的值(像素RGB 通道的计算十六进制值),但事实并非如此。即使正确的值是从我的控制器记录的。
这是我的控制器:
module.controller('LiveController', function($scope, $data)
$scope.hex = '00FFFF';
var pictureSource;
var destinationType;
document.addEventListener("deviceready", onDeviceReady, true);
function onDeviceReady()
console.log('onDeviceReady');
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
capturePhoto();
function capturePhoto()
console.log('capturePhoto');
navigator.camera.getPicture(onSuccess, onFail,
quality: 50,
destinationType: destinationType.DATA_URL
);
function onSuccess(imageData)
console.log('onSuccess');
var largeImage = document.getElementById('largeImage');
largeImage.style.display = 'block';
largeImage.src = "data:image/jpeg;base64," + imageData;
setupImage(imageData);
function onFail(message)
console.log('Failed because: ' + message);
function getMousePos(canvas, evt)
var rect = canvas.getBoundingClientRect();
return
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
;
function init(imageObj)
console.log('init');
var padding = 10;
var mouseDown = false;
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.strokeStyle = '#444';
context.lineWidth = 2;
context.canvas.width = window.innerWidth;
context.canvas.height = window.innerWidth;
canvas.addEventListener('mousedown', function()
mouseDown = true;
, false);
canvas.addEventListener('mouseup', function()
mouseDown = false;
, false);
canvas.addEventListener('mousemove', function(evt)
console.log('mousemove');
var mousePos = getMousePos(canvas, evt);
var color = undefined;
if (mouseDown && mousePos !== null && mousePos.x > padding && mousePos.x < padding + imageObj.width && mousePos.y > padding && mousePos.y < padding + imageObj.height)
var imageData = context.getImageData(padding, padding, imageObj.width, imageObj.width);
var data = imageData.data;
var x = mousePos.x - padding;
var y = mousePos.y - padding;
var red = data[((imageObj.width * y) + x) * 4];
var green = data[((imageObj.width * y) + x) * 4 + 1];
var blue = data[((imageObj.width * y) + x) * 4 + 2];
var color = 'rgb(' + red + ',' + green + ',' + blue + ')';
console.log('picked color is ' + color);
updateColor(red, green, blue);
, false);
context.drawImage(imageObj, padding, padding);
function updateColor(R, G, B)
$scope.hex = rgbToHex(R, G, B);
console.log($scope.hex);
function rgbToHex(R, G, B)
return toHex(R) + toHex(G) + toHex(B)
function toHex(n)
n = parseInt(n, 10);
if (isNaN(n))
return "00";
n = Math.max(0, Math.min(n, 255));
return "0123456789ABCDEF".charAt((n - n % 16) / 16) + "0123456789ABCDEF".charAt(n % 16);
function setupImage(_data)
console.log('setupImage');
var imageObj = new Image();
imageObj.onload = function()
init(this);
;
imageObj.src = "data:image/jpeg;base64," + _data;
);
重要的部分在mousemove
事件监听器之后开始。我得到了 RGB 值并将它们转换为十六进制。这一切都很好 - RGB和HEX。但是$scope.hex
似乎永远不会绑定/更新视图。请告知发生了什么问题。
【问题讨论】:
【参考方案1】:尝试将您的 updateColor() 函数编辑为如下所示。
function updateColor(R, G, B)
$scope.hex = rgbToHex(R, G, B);
console.log($scope.hex);
$scope.$apply();
这应该可行。您可能遇到的问题是您正在更新 hex 的值,但 Angular 可能无法识别更改。 $scope.$apply() 应该强制绑定更新,从而解决您的问题。
【讨论】:
成功了——干杯。将在几分钟内接受。永远不知道什么时候使用 apply() - 它以前给过我抱怨,所以我倾向于回避......应该试着更好地理解它。 仅供参考:github.com/angular/angular.js/wiki/When-to-use-$scope.$apply() @jesses.co.tt 谢谢!最好的方法(我认为)是,每当你做一些不是通过一些 Angular 助手或服务完成的异步操作时,你应该使用 $scope.$apply()。【参考方案2】:我相信在您的情况下,当您使用鼠标移动事件时,角度不会意识到变化,因为它是异步运行的。 包装'updateColor(red, green, blue);'的调用$scope.$apply 中的方法会有所帮助。
所以你将拥有:
$scope.$apply(function ()
updateColor(red, green, blue);
);
不仅仅是:
updateColor(red, green, blue);
您也可以使用不带参数的 $scope.$apply(),但请看这里 http://jimhoskins.com/2012/12/17/angularjs-and-apply.html 他们解释了为什么前一种方法更受欢迎。
【讨论】:
好答案...只是太慢了! :D以上是关于角度变量未绑定到视图的主要内容,如果未能解决你的问题,请参考以下文章