Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write directive on class in Angular Js?

The restrict option is typically set to:

'A' - only matches attribute name
'E' - only matches element name
'C' - only matches class name
'M' - only matches comment

'C' - only matches class name is not working

Class="form-control **valid-vehicleyear** ng-not-empty ng-dirty ng-valid-parse ng-valid ng-valid-required ng-touched"

I created a directive on class associated with element. On change of value i want to call a api and change value of other element. But no change is observed on change.

controlDirective.js

  function validVehicleyear($scope, $http) {
        return {
            restrict: 'C',
            scope: {
                ngModel: '=',                
            },
            link: function (scope, element, attrs, ngModel) {
                element.bind('change', function () {
                    console.log('here in validVehicleyear');
                    $http.get('api.php'+scope.ngModel)
                            .then(function (response) {
                                $scope.answers.VehicleMake = response.data;
                            });
                });
            }
        }
    }

Vehicle year question has a class valid-vehicleyear. what I am missing here, or is there any other to this on change of answers.vehicleyear. I wrote a directive validVehicleyear on class at Vehicle year question, this i want to call on change of year and set new options for Vehicle make, but it not working.

plnkr.co/edit/BFGXr7LNAe0KvQipj9JJ?p=preview

I checked around and found that outer/inner directive concept can work here. but not getting how to apply for the dynamic classes.

like image 688
pandu das Avatar asked Aug 08 '16 05:08

pandu das


2 Answers

Back from your other question, I tried a couple of things none of which worked for this reason:

You pass a directive as a class but dynamically by interpolation which in itself is bad practice (https://docs.angularjs.org/guide/interpolation#known-issues). The class name is interpolated and the element rendered but the directive is not compiled during interpolation.

The only thing that worked was to pass the directive name in clear:

class="form-control valid-vehicleyear"

But then all your select elements will have this class/directive.

You're trying to automate everything and you're pushing the concept to the extreme which makes your code very unreadable and apparently impossible to debug.

There's nothing wrong with building a form element by element and putting custom directives on each of them for better control.

However there is everything wrong with passing dynamic directives as classes from a JSON object.

Just build your form normally. It won't be less cool or less readable and it will follow best practice (https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#restrict-to-elements-and-attributes)

<select valid-vehicleyear>
<select valid-makemodel>
...
like image 150
gyc Avatar answered Sep 18 '22 04:09

gyc


Some issues in your code:

  • Isn't necessary use scope: { ngModel: '='}. Instead use require.
  • For access to the value of the ngModel value passed like 4th argument, use ngModel.$viewValue.
  • If you need access to the variable of your controller, you have 2 posibilities.
    1. remove the scope property for get a shared scope with the controller, and access directly to the answers variable through the scope passed in the link function like this scope.answers.
    2. This it's the better option. sharing access to the answers variables within the isolated scope property of your directive. scope: { answers: '=' }

The modified code:

function validVehicleyear($http) {
    return {
      restrict: 'C',
      require: 'ngModel',
      link: function (scope, element, attrs, ngModel) {
        element.bind('change', function () {
          console.log('here in validVehicleyear');
          $http.get('api.php' + ngModel.$viewValue)
            .then(function (response) {
              scope.answers.VehicleMake = response.data;
            });
          });
        }
      }
    }

My final recommendation it's not use the Class option, in your case, it's better use the Attribute option. Good luck!

like image 33
Gonzalo Pincheira Arancibia Avatar answered Sep 18 '22 04:09

Gonzalo Pincheira Arancibia