Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

loop through the provided attributes

I am new to angular, I have a requirement where I need to add many custom attributes to a custom element directive, <radio-button>. Currently, I am doing like this:

<radio-button one-attr="some value" two-attr="some string" three-attr="some other string"><radio-button>

I have many radio buttons on the page and writing custom attributes to each custom directive on that page looks messy. So, I am looking for an alternative where I can pass a javascript array object which loops on each radio-button custom directive.

For example: (In controller)

  $scope.values = [{
       'one-attr': 'some value',
       'two-attr': 'some other value',
       'three-attr': 'another value',
       /* and so on... */
  },
  {
       /* another custom attribute set */
  }
  /* so on */
  ]

and then to my custom directive, I will pass an custom attribute directive as shown below:

  <radio-button ng-repeat="(key, value) in values" loop-attributes="key, value"></radio-button>

Where above loop-attributes is a custom attribute directive applied to the custom element directive.

Please suggest how to do this.

If I am going wrong please suggest me how to handle this.

like image 949
Mr_Green Avatar asked Oct 30 '22 23:10

Mr_Green


2 Answers

You would most probably have to use $compile service as radiobutton is a custom directive. You could have a parent directive which has a list of attributes and within the directive create radiobutton element with attributes and then compile it. Have used input type for example.

http://plnkr.co/edit/7ANndIuHCFaGyjWkw7sa?p=preview

// custom element
.directive('customInput', function() {
  return {
    replace: true,
    restrict: 'E',
    template: '<input type="text"></input>'
  };
})

//wrapper directive
.directive('customInputAttr', function($compile) {
  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
      // This could be set even in controller
      scope.elemAttrs = [{
        'class': 'class1',
        'ng-model': 'input1'
      }, {
        'class': 'class2',
        'ng-model': 'input2'
      }];

      angular.forEach(scope.elemAttrs, function(elemAttr) {
        var customInputElem = angular.element('<custom-input></custom-input>');
        angular.forEach(elemAttr, function(value, key) {
          customInputElem.attr(key, value)
        });

      var elem = $compile(customInputElem)(scope);
      element.append(elem);
      });

    }
  };
})
like image 134
Bharat Avatar answered Nov 11 '22 04:11

Bharat


You will want to use a directive that replaces itself with other directives. You can see here for how to do that. I have made a jsfiddle to show you how this works. The repeat must be on an outer element and not the element containing the directive itself. This is because your custom-attr directive will be parsed before the ng-repeat gets parsed, so it won't yet have a value for attr.

EDIT: I left out an import step at the end of the link function, sorry. This updated fiddle should work. You need to recompile the directive to make your added ng-click directive actually function. You also have to make sure to make the function you're binding ng-click to available to that scope, either by passing it in or by using ng-click="$parent.foo()"

like image 44
Nik Klassen Avatar answered Nov 11 '22 06:11

Nik Klassen