What is the best way to conditionally apply attributes in AngularJS? – Dev

The best answers to the question “What is the best way to conditionally apply attributes in AngularJS?” in the category Dev.

QUESTION:

I need to be able to add for example “contenteditable” to elements, based on a boolean variable on scope.

Example use:

<h1 attrs="{'contenteditable=\"true\"': editMode}">{{content.title}}</h1>

Would result in contenteditable=true being added to the element if $scope.editMode was set to true.
Is there some easy way to implement this ng-class like attribute behavior? I’m considering writing a directive and sharing if not.

Edit:
I can see that there seems to be some similarities between my proposed attrs directive and ng-bind-attrs, but it was removed in 1.0.0.rc3, why so?

ANSWER:

You can prefix attributes with ng-attr to eval an Angular expression. When the result of the expressions undefined this removes the value from the attribute.

<a ng-attr-href="https://stackoverflow.com/questions/15696416/{{value"| undefined}}">Hello World</a>

Will produce (when value is false)

<a ng-attr-href="https://stackoverflow.com/questions/15696416/{{value"| undefined}}" href>Hello World</a>

So don’t use false because that will produce the word “false” as the value.

<a ng-attr-href="https://stackoverflow.com/questions/15696416/{{value"| false}}" href="false">Hello World</a>

When using this trick in a directive. The attributes for the directive will be false if they are missing a value.

For example, the above would be false.

function post($scope, $el, $attr) {
      var url = $attr['href'] || false;
      alert(url === false);
}

ANSWER:

I am using the following to conditionally set the class attr when ng-class can’t be used (for example when styling SVG):

ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"

The same approach should work for other attribute types.

(I think you need to be on latest unstable Angular to use ng-attr-, I’m currently on 1.1.4)

ANSWER:

In the latest version of Angular (1.1.5), they have included a conditional directive called ngIf. It is different from ngShow and ngHide in that the elements aren’t hidden, but not included in the DOM at all. They are very useful for components which are costly to create but aren’t used:

<h1 ng-if="editMode" contenteditable=true>{{content.title}}</h1>

ANSWER:

I got this working by hard setting the attribute. And controlling the attribute applicability using the boolean value for the attribute.

Here is the code snippet:

<div contenteditable="{{ condition ? 'true' : 'false'}}"></div>

I hope this helps.