Marcio Cruz
Marcio Cruz

Reputation: 2069

AngularJS directive fails to render replaced DOM

I'm trying to make a simple directive that replaces a span with another span binding to 2 attributes of the scope:

.directive('exCategory', function () {
    return {
        restrict: 'A',
        scope: {
            category: '=exCategory'
        },
        replace: true,
        template: '<span class="category-label" ng-bind="category.name" style="background-color: {{category.color}};"></span>',
        link: function (scope, element) {
            console.log(scope, element);

        }
    };
})

This is my html:

<span ex-category="transaction.category"></span>

When rendered, it does nit give the color, and raises the following error on the console:

TypeError: Cannot read property 'length' of undefined
    at $interpolate (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js:5318:24)
    at attrInterpolateLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js:4987:27)
    at nodeLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js:4774:13)
    at compositeLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js:4365:15)
    at compositeLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js:4368:13)
    at compositeLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js:4368:13)
    at publicLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js:4270:30)
    at ngRepeatAction (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js:14945:15)
    at Object.$watchCollectionAction [as fn] (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js:8476:11)
    at Object.Scope.$digest (https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js:8570:27) <span class="category-label" style="background-color: {{category.color}};;background-color: {{category.color}};" ex-category="transaction.category">

Something seems wrong with the generated DOM:

<span class="category-label" style="background-color: {{category.color}};;background-color: {{category.color}};" ex-category="transaction.category">

If I remove the color bit, it works.

Any suggestions?

Edit: If I use the hit I want to render directly on my template, it works.

Edit: the problem seems to be related with the style tag:

template: '<span class="category-label" ng-bind="category.name" style="aaa">{{category.color}}</span>'

renders:

<span class="category-label ng-binding" ng-bind="category.name" style="aaa;aaa" ex-category="transaction.category">asdads</span>

The problem does not happen with version 1.0.1. JSFiddle with the problem occurring on 1.1.5:

http://jsfiddle.net/marcio0/a5KLT/

Upvotes: 3

Views: 1221

Answers (2)

Aleksander Blomsk&#248;ld
Aleksander Blomsk&#248;ld

Reputation: 18552

This looks like a bug in the Angular 1.1x-branch. The only work-around I can come up with is to remove the style in your template and manually setup a watch in your link-function:

template: '<span class="category-label" ng-bind="category.name"></span>',
link: function (scope, element) {
    scope.$watch('category.color', function() {
        element.attr('style', 'background-color: ' + scope.category.color + ';');
   });

Update

Using ng-style is of course a much better idea.

Upvotes: 1

Gloopy
Gloopy

Reputation: 37785

Instead of using style="background-color: {{category.color}};" try using ng-style like this:

ng-style="{backgroundColor: category.color}"

Here is an updated fiddle that will create the markup you want consistently.

Upvotes: 4

Related Questions