I want to use ng-model with an external model-service. This model has two methods: getValue(variable) and setValue(variable).
So in my html I want to be able to do:
<input type="text" ng-model="balance">
Note: balance is not defined on $scope in my controller. And because we are dealing with more then 4000 different variables, I don't want to define them all on $scope.
And then on change it must call the setValue() method of the model. So in my controller I would like to have something like:
$catchAllGetter = function(variable) { // e.g. variable = 'balance'
var value = Model.getValue(variable);
return value;
}
$catchAllSetter = function(variable, value) { // called on change
Model.setValue(variable, value);
}
Is something like this possible with Angular?
My approach is similar to @Dan Prince, but the implementation differs a bit
Create a directive, that accepts name of the model variable, and then inject your model service in the directive itself to perform the getting and setting.
Edit : As specified by @Werlang, writing an attribute that replaces ngModel will refrain you from features like validation, formatting, debounced update, ng-change etc. So instead of writing a replacement, we will instead wire up a supplementary attribute
.
app.directive('dynamicInput', function() {
return {
restrict: 'A',
link: function(scope, el, attr) {
scope.variableName = angular.copy(attr.ngModel); // Saving the variable name
scope[attr.ngModel] = (attr.ngModel + '_1'); // Setting a dummy value in the scope variable.
// In your case it will look something like scope[attr.ngModel] = Model.getValue(attr.ngModel);
scope.$watch(attr.ngModel, function(newValue, oldValue) {
console.log(scope.variableName + " ==> " + newValue);
//Model.setValue(scope.variableName, newValue);
});
}
};
})
Then in your HTML :
<input ng-model='balance' dynamic-input />
You can create a new directive which implements this behaviour.
<input model-getter='getFn()' model-setter='setFn($value)' />
This would be fairly straightforward to implement:
app.directive('modelGetter', function() {
return {
restrict: 'A',
scope: {
get: '&modelGetter',
set: '&modelSetter'
},
link: function(scope, element) {
element.val(scope.get());
element.on('change', function() {
var val = element.val();
scope.set({ $value: val });
});
}
};
})
look at example, i created for you. I hope I have understood you correctly
$scope.$watch('variables', function(newValue) {
console.log("triggers on variables change");
angular.forEach(newValue, function(value, key) {
Model.setValue(key, value);
});
}, true);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With