I've a long calculation form and want to prefill some values for displaying initial results. These initial values should live in the template to have these easily editable. It seems, the angular way is to use a directive which reads the input value fields and initializes the app with these values.
Here is one way to to set the model value from the input field:
<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>
Coffeescript:
app = angular.module 'forms', []
app.directive 'ngInitial', ->
restrict: 'A'
controller: ['$scope', '$element', '$attrs', '$parse', ($scope, $element, $attrs, $parse) ->
val = $attrs.sbInitial || $attrs.value
getter = $parse($attrs.ngModel)
setter = getter.assign
setter($scope, val)
]
Source: Angular js init ng-model from default values
Unfortunately this doesn't work in my app. The values are displayed but the results aren't calculated. I have to manual fill out the fields in the browser to start the calculation.
The input fields are watched in my controller, like so:
$scope.$watch(
'inputValues.permeatCapacity',
function (newValue, oldValue) {
if (newValue === oldValue) {
return;
}
permeatCapacity = $scope.inputValues.permeatCapacity;
permeatPerDay = permeatFactory.getPermeatPerDay(permeatCapacity);
$scope.permeatPerDay = $filter('number')(permeatPerDay, 2);
}
);
What's the best directive for this problem or is there a better way in Angular.js?
UPDATE
I've just found a really dirty way in the controller to update the input fields after initialization that make use of the bound calculations. It not only feels like an bad idea, the initial values also don't live in the template:
$timeout(function () {
$scope.inputValues.overallRecovery = 40;
$scope.inputValues.permeatCapacity = 7.2;
}, 0);
In comparison, this initial object in my controller fills out the fields but doesn't trigger the watchers (important for the bound calculations):
$scope.inputValues = {
overallRecovery: 40,
permeatCapacity: 7.2
};
But there is a better way to do this, isn't it?