amcdnl
amcdnl

Reputation: 8648

AngularJS ng-class usage in Directive

I have a directive that in its template has ng-class usage. When I try to add ng-class to the parent 'useage' element, it blows up saying:

Error: [$parse:syntax] Syntax Error: Token '{' is an unexpected token at column 48 of the expression [{ 'active': $stateParams.recordId === row.id } 
{ 'ng-table-selected': selectedRow && selectedRow.id === row.id }] starting at [{ 'ng-table-selected': selectedRow && selectedRow.id === row.id }].
http://errors.angularjs.org/1.2.14/$parse/syntax?

Whats the proper way to handle something like this?

parent usage html:

<div ng-table-row ng-repeat="row in results"
         ng-class="{ 'active': $stateParams.recordId === row.id }"
         row-click="rowClick(row)"></div>

directive html:

<div class="ng-table-table-row"
 ng-click="rowClicked(row, $event)"
 ng-class="{ 'ng-table-selected': selectedRow && selectedRow.id === row.id }"
 ng-style="{ height: tableOptions.rowHeight, top: rowTop, width: rowWidth }"
 ng-transclude></div>

directive JS:

module.directive('ngTableRow', function ($rootScope) {
    return {
        restrict: 'AE',
        replace: true,
        transclude: true,
        templateUrl: 'common/components/table/views/row.tpl.html',
        link: function ($scope, $element, $attributes) {
            $scope.rowTop = $scope.$index * $scope.tableOptions.rowHeight;

            $scope.rowClicked = function(row){
                // body listener to set active
                $scope.bodyRowClicked(row);

                // row click public api
                $scope.rowClick({
                    row: row
                });
            };
        } 
    };
});

Upvotes: 0

Views: 340

Answers (1)

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40318

I believe the reason is specifying ng-class both in the placeholder and in the template of a replace: true directive. Angular will replace the <div ng-table-row> with the directive's template and apply ng-class from <div ng-table-row> to the template's root element, which also has a ng-class directive. These will probably get mixed-up and cause the problem.

In your case the solution may be as easy as applying the CSS class manually in the link():

scope.$watch(
    function() {
        return scope.selectedRow && scope.selectedRow.id === scope.row.id;
    },
    function(newval) {
        elem.toggleClass("ng-table-selected", newval);
    }
);

(Assuming of course selectedRow and row are in the scope.)

Upvotes: 1

Related Questions