Это очень хороший вопрос, и я ответить на него, даже если он уже принял :)
В Угловом, то $ сфера является моделью. Модель - это место для хранения данных, которые вы, возможно, захотите сохранить или использовать в других частях приложения, и как таковой, она должна быть разработана с хорошей схемой так же, как и в базе данных, например.
Ваша модель имеет два избыточных поля для температуры, что не является хорошей идеей. Какая из них «настоящая» температура? Бывают случаи, когда вы хотите денормализовать модель, только для эффективности доступа, но это только вариант, когда значения являются идемпотентными, что, как вы обнаружили, не связано с точностью с плавающей запятой.
Если вы хотите продолжить использование модели, это будет выглядеть примерно так. Вы выбрали бы одну или другую как температуру «источника истины», а затем использовали бы другой вход в качестве удобного окна ввода с форматированием и парсером. Допустим, мы хотим Фаренгейта в модели:
<input type="number" ng-model="temperatureF">
<input type="number" ng-model="temperatureF" fahrenheit-to-celcius>
И директивы преобразования:
someModule.directive('fahrenheitToCelcius', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$formatters.push(function(f) {
return (value - 32) * 5.0/9.0;
});
ngModel.$parsers.push(function(c) {
return c * 9.0/5.0 + 32;
});
}
};
});
При этом, вы бы избежать «подпрыгивая», потому что $ парсеры работать только на действия пользователя не по изменению модели. У вас все еще будут длинные десятичные знаки, но это можно было бы исправить округлением.
Однако это звучит так, как будто вы не должны использовать модель для этого. Если все, что вам нужно, - «каждый ящик обновляет другое поле», вы можете сделать именно это и даже не иметь модель. Это предполагает, что поля ввода начинают пустым, и это простой инструмент для пользователей, чтобы преобразовывать температуры. Если это так, у вас нет модели, нет контроллера и даже вряд ли можно использовать Angular. В данный момент это чисто виджет-виджет, и в основном это jQuery или jQLite. Однако он имеет ограниченную полезность, поскольку без модели он не может воздействовать ни на что другое в Angular.
Для этого вы можете просто создать директиву temperatureConverter
, в которой есть шаблон с несколькими полями ввода, и следит за обеими ячейками и задает их значения. Что-то наподобие:
fahrenheitBox.bind('change', function() {
celciusBox.val((Number(fahrenheitBox.val()) - 32) * 5.0/9.0);
});
Причина, по которой это хороший вопрос, состоит в том, что эта ситуация имеет бесконечный цикл во всем этом - если вычисления не были обратными друг другу ... +1. И я буду удивлен, увидев любые другие разные ответы. – rGil
Из-за фона в DSP мне трудно противостоять математике, поэтому я просто отдам его: возможно, это перейдет в бесконечный цикл (за исключением того, что у Angular есть встроенный предел максимальных итераций). Вот отличное объяснение того, почему значения «отскок» вообще (из-за грязной проверки): http://stackoverflow.com/a/9693933/885163. И в сочетании с ограниченной точностью с плавающей запятой возможно, чтобы значения осциллировали 0, 1 или более раз, даже неопределенно, эффект, известный как «предельный цикл» в фильтрах DSP IIR. * phew * как это для комментария? –