华氏和摄氏双向转换在AngularJS [英] Fahrenheit and Celsius Bidirectional Conversion in AngularJS
问题描述
在AngularJS,这是简单的如何$观看$范围的变量,并用它来更新另一个。但是,什么是最好的做法如果两个范围内的变量需要看对方?
In AngularJS, it is straightforward how to $watch a $scope variable and use that to update another. But what is the best practice if two scope variables need to watch each other?
我有,例如,一个双向转换器,将华氏转换为摄氏度,反之亦然。如果键入1进入华氏,但尝试1.1和角度会反弹,有点华氏覆盖之前您刚才输入是一个稍微不同的值(1.1000000000000014)这工作好:
I have as an example a bidirectional converter that will convert Fahrenheit to Celsius, and vice versa. It works okay if you type "1" into the Fahrenheit, but try "1.1" and Angular will bounce around a little before overwriting Fahrenheit that you just entered to be a slightly different value (1.1000000000000014):
function TemperatureConverterCtrl($scope) {
$scope.$watch('fahrenheit', function(value) {
$scope.celsius = (value - 32) * 5.0/9.0;
});
$scope.$watch('celsius', function(value) {
$scope.fahrenheit = value * 9.0 / 5.0 + 32;
});
}
下面是一个plunker:<一href=\"http://plnkr.co/edit/1fULXjx7MyAHjvjHfV1j?p=$p$pview\">http://plnkr.co/edit/1fULXjx7MyAHjvjHfV1j?p=$p$pview
Here's a plunker: http://plnkr.co/edit/1fULXjx7MyAHjvjHfV1j?p=preview
有哪些不同的可能的方式来从反弹周围停转并迫使它使用您键入原样,例如价值通过使用格式化或解析器(或任何其他伎俩)?
What are the different possible ways to stop Angular from "bouncing" around and force it to use the value you typed as-is, e.g. by using formatters or parsers (or any other trick)?
推荐答案
我觉得最简单,最快,最正确的解决办法是有一个标志来跟踪哪些领域正在被编辑,只允许从该领域的更新。
I think the simplest, fastest, and most correct solution is to have a flag to track which field is being edited, and only allow updates from that field.
您只需要使用 NG-变化
指令设置标志场上正在编辑中。
All you need is to use the ng-change
directive to set the flag on the field being edited.
code必要的修改:
Code changes necessary:
修改控制器看起来是这样的:
Modify the controller to look like this:
function TemperatureConverterCtrl($scope) {
// Keep track of who was last edited
$scope.edited = null;
$scope.markEdited = function(which) {
$scope.edited = which;
};
// Only edit if the correct field is being modified
$scope.$watch('fahrenheit', function(value) {
if($scope.edited == 'F') {
$scope.celsius = (value - 32) * 5.0/9.0;
}
});
$scope.$watch('celsius', function(value) {
if($scope.edited == 'C') {
$scope.fahrenheit = value * 9.0 / 5.0 + 32;
}
});
}
然后这个简单的指令添加到输入字段(使用˚F
或 C
如适用):
<input ... ng-change="markEdited('F')/>
现在仅领域正在键入在可改变的另一个。
Now only the field being typed in can change the other one.
如果您需要修改的能力,这些领域的之外的输入,你可以添加,看起来像这样的范围或控制器功能:
If you need the ability to modify these fields outside an input, you could add a scope or controller function that looks something like this:
$scope.setFahrenheit = function(val) {
$scope.edited = 'F';
$scope.fahrenheit = val;
}
然后摄氏度场将在接下来的$更新周期消化
Then the Celsius field will be updated on the next $digest cycle.
此溶液具有的额外code进行最低限度,消除了每个周期的多个更新的任何机会,并不会导致任何性能问题。
This solution has a bare minimum of extra code, eliminates any chance of multiple updates per cycle, and doesn't cause any performance issues.
这篇关于华氏和摄氏双向转换在AngularJS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!