Angular directive: adding an ng class directive while compiling an existing template element

In short, the idea is to simplify templating without manually adding ng-class={'has-error': 'formName.inputName.$invalid'}to eachform-group

So, I want to create a directive that will generate a string to be added to the template element. This string is an attribute ng-classwith expression

I thought that creating a quick directive that adds the ng-class attribute during the compilation phase would be enough, but doesn't seem to shorten it.

Directive Definition Object

{
    restrict: 'C',
    compile: 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'));
    }
}

Post here

See console

The first form-groupadds an attribute ng-classadded dynamically.
The corresponding expression is correct. But the directive is ng-classnever executed

form-group ng-class, , obvisouly

-

?

+4
2

(, ng- , )

DOM postLink, , . , "form-group"

function bsFormClass($compile) {
  return {
    restrict: 'A',

    compile: 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) {
                $compile(elem)(scope);
            }
        }
    }
  }
}

,

+5

!

; :

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);
            });
        }
    };
}

ng-class ... . forked plunk: http://plnkr.co/edit/oKa6CKFoF1T5WoDzIPkI?p=preview

+2

Source: https://habr.com/ru/post/1618491/


All Articles