Generic Angular Components – Optional Bindings

I would utilise the fact that the template property can be a function (tElem, tAttrs) { ... } (docs) that returns a string to modify the template based on the attributes present.

The way I would do this is to use jQuery and some custom elements to indicate which parts of the template are conditional.

Here is a quick sample template function:

function template($element, $attrs) {
  var fullTemplate = $('<div><if-attr name="a"><div ng-if="$ctrl.a"></div></if-attr></div>');
  fullTemplate.find('if-attr').each(function() {
    if (attrs.hasOwnProperty($(this).attr('name'))) {
      $(this).replaceWith(this.innerHTML);
    } else {
      $(this).remove();
    }
  });
  return fullTemplate[0].outerHTML;
}

Sample output

template(null, {a: '1'}) => "<div><div ng-if="$ctrl.a"></div></div>"
template(null, {b: '1'}) => "<div></div>"

Known Limitations

This breaks down if you wanted to fetch the template from a URL (and it isn’t prepopulated in the $templateCache) but that doesn’t appear to be your situation.

If Minifying

The documentation states that if template is a function, it is injected with $element and $attrs. That means that if you are minifying your code, make sure you use a minification-safe method of specifying the function parameter names.
e.g.

template: ['$element', '$attrs', function ($elem, $attrs) { 
    // ...
}],

or

function templateFn($elem, $attrs) { 
    // ...
}
templateFn['$inject'] = ['$element', '$attrs'];

template: templateFn,

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)