5

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.

Mr_Green
  • 40,727
  • 45
  • 159
  • 271
  • 1
    Consider moving that up one more level and have a directive for the group of radios and use `name` in hashmap object to store arrays for values, labels and properties like `ng-model` `ng-messages` etc. Then use child directive in group template for each input – charlietfl Jul 23 '15 at 16:15
  • Can you please provide a small example? – Mr_Green Jul 24 '15 at 02:39
  • 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. I will see if i can come up with an example. – Bharat Jul 24 '15 at 06:14
  • @Bharat thanks. it will be really helpful for me to give an example. – Mr_Green Jul 24 '15 at 06:17

2 Answers2

1

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()"

Community
  • 1
  • 1
Nik Klassen
  • 681
  • 8
  • 16
1

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

    }
  };
})
Bharat
  • 943
  • 7
  • 9