admin管理员组文章数量:1287655
Long story short, the idea is to simplify templating by not having to manually add ng-class={'has-error': 'formName.inputName.$invalid'}
on every single form-group
So I want to create a directive that will generate a string that will be added to a template element. That string is an ng-class
attribute with an expression
I thought that creating a quick directive that adds the ng-class attribute during the pile phase would be enough, but it doesn't seem to cut it.
Directive Definition Object
{
restrict: 'C',
pile: function(tElement, tAttrs) {
var $elem = angular.element(tElement),
formName = $elem.parents('[ng-form]').length ? $elem.parents('[ng-form]').attr('ng-form') : $elem.parents('form').attr('name'),
controlName = $elem.find('.form-control').attr('name');
$elem.attr('ng-class', '{"has-error": ' + formName + '.' + controlName + '.$invalid}');
console.log('added ng-class attr', $elem.attr('ng-class'));
}
}
Plunk here
See the console
The 1st
form-group
has itsng-class
attribute added dynamically.
The expression associated with it is correct
But theng-class
directive is never executedThe 2nd
form-group
has itsng-class
attribute added manually in the template and works as expected, obvisouly
--
What am I missing here?
Long story short, the idea is to simplify templating by not having to manually add ng-class={'has-error': 'formName.inputName.$invalid'}
on every single form-group
So I want to create a directive that will generate a string that will be added to a template element. That string is an ng-class
attribute with an expression
I thought that creating a quick directive that adds the ng-class attribute during the pile phase would be enough, but it doesn't seem to cut it.
Directive Definition Object
{
restrict: 'C',
pile: function(tElement, tAttrs) {
var $elem = angular.element(tElement),
formName = $elem.parents('[ng-form]').length ? $elem.parents('[ng-form]').attr('ng-form') : $elem.parents('form').attr('name'),
controlName = $elem.find('.form-control').attr('name');
$elem.attr('ng-class', '{"has-error": ' + formName + '.' + controlName + '.$invalid}');
console.log('added ng-class attr', $elem.attr('ng-class'));
}
}
Plunk here
See the console
The 1st
form-group
has itsng-class
attribute added dynamically.
The expression associated with it is correct
But theng-class
directive is never executedThe 2nd
form-group
has itsng-class
attribute added manually in the template and works as expected, obvisouly
--
What am I missing here?
Share Improve this question edited Dec 3, 2015 at 21:58 Olivier Clément asked Dec 3, 2015 at 21:12 Olivier ClémentOlivier Clément 7641 gold badge9 silver badges27 bronze badges2 Answers
Reset to default 6Managed to make it work without adding extra watchers (granted, ng-class uses a watcher, but after testing the proposed solution I saw an increase in watchers amount)
I had to $pile the new DOM element in postLink, but to avoid recursion I need to remove the directive itself. This prevents me to reuse a class-name such as "form-group"
Here's the working Directive
function bsFormClass($pile) {
return {
restrict: 'A',
pile: function (tElement) {
var $elem = angular.element(tElement),
controlName = $elem.find('.form-control').attr('name');
if(!controlName) { return; }
var formName = $elem.parents('[ng-form]').length ? $elem.parents('[ng-form]').attr('ng-form') : $elem.parents('form').attr('name');
$elem.attr('ng-class', '{"has-error": ' + formName + '.' + controlName + '.$invalid}');
$elem.removeAttr('bs-form-class');
return {
post: function(scope, elem, attrs) {
$pile(elem)(scope);
}
}
}
}
}
Thanks for you help all
You cannot add directives to the current element!
In your case the solution is easy though; just watch the appropriate expressions and add the class as necessary:
function formGroupClass () {
return {
restrict: 'C',
link: function(scope, elem, attrs) {
var formName = elem.parents('[ng-form]').length ? elem.parents('[ng-form]').attr('ng-form') : elem.parents('form').attr('name'),
controlName = elem.find('.form-control').attr('name');
scope.$watch(formName + '.' + controlName + '.$invalid', function(newval) {
elem.toggleClass('has-error', !!newval);
});
}
};
}
The ng-class
would add a watch anyway... See forked plunk: http://plnkr.co/edit/oKa6CKFoF1T5WoDzIPkI?p=preview
本文标签:
版权声明:本文标题:javascript - Angular Directive: Adding ng-class directive at compile time on existing template element - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741315603a2371895.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论