A JSFiddle is here:
The problem description is as follows, I have a controller wrapping a form which contains some logic, and can not be defined within the directive hash as controller:
I need the ability to populate a field from a directive dynamically like so:
App.Directive.SomeAwesomeDirective = ->
restrict: 'C'
link: (scope, element, attrs) ->
someValue = scope.someValue
field = element.find(".some-class")
scope.fieldValue = someValue
field.ngModel = "scope.fieldValue"
field.ngClass = "scope.someAwesomeClass"
monitorFields = (newValue, oldValue) ->
console.log "we are here"
console.debug newValue
console.debug oldValue
scope.addValue(newValue)
scope.$watch "scope.fieldValue", monitorFields, true
I need the following to be fulfilled:
1) When the textfields value is changed, I want scope.fieldValue to be updated. 2) After this happens, I want the addValue method (defined on the wrapping controller), to be called with the new value for validation. 3) The addValue method should set the someAwesomeClass scope variable, and the input fields class should update. 4) The ngClasses to be applied are ng-valid/ng-invalid. Form validation should function correctly in correspondence with these classes
As can be seen in my jsfiddle, none of these things are currently happening, and I am unsure as to why...
Thanks!
You can fix it by defining a directive someClass
, which will execute the function on its parent. The form
tag gets an extra attribute execute
, which holds the function to execute. The someClass
directive will search the controller of dir
directive (hence require: '^dir') and execute it.
Another solution would have been to drop the dir
directive and define the execute
attribute on the someClass
directive (e.g. when each input field should trigger a different function).
<form class="dir" execute="someFunction">
Directives:
app.directive('dir', function () {
return {
restrict: 'C',
scope: {
execute: '='
},
controller: function ($scope) {
this.execute = $scope.execute;
}
};
});
app.directive('someClass', function () {
return {
restrict: 'C',
require: '^dir',
replace: true,
template: '<INPUT name="foo" id="bar" type="text" ng-model="fieldValue" >',
scope: {
fieldValue: '@'
},
link: function (scope, elm, attrs, ctrl) {
var monitorField = function (newValue, oldValue) {
if (newValue) {
ctrl.execute(newValue);
}
};
scope.$watch("fieldValue", monitorField, true);
}
};
});
See jsFiddle.