3

Let's assume I've got a few objects that have the same prototype and I want to customize their display in Angular template. I know I can create my own filter, and then use it like that:

<p>{{anObjectOfProtoP | myCustomFilter}}</p>

or a function attached to $scope:

<p>{{myCustomFunction(anotherObjectOfProtoP)}}</p>

My question is: is it possible to achieve similar functionality without explicitly specifying the rendering function every time? The ideal solution would be if angular checked for function toAngularString on object inside the {{}}, and then used it's return value in template. In other words, I'd like Angular to do

function (o) {
   if (typeof o.toAngularString === 'function') return o.toAngularString();
   return o;
}

on every object inside {{}}.

Wojciech Ptak
  • 683
  • 4
  • 14

1 Answers1

4

Depending on whether you use {{ ... }} or ng-bind syntax, the .toJSON and the .toString function on your object will be called to determine its representation. Hence, you can provide the representation you want in either .toString or .toJSON function of your object.

This discrepancy in which function is called has let to some problems, actually.

Another way you can do that is by writing your own directive my-toangularstr as this:

app.directive('myToangularstr', function () {
  return {
    scope: true,
    template: '<span class="my-angular-value">{{ val.toAngularString() }}</span>',
    link: function (scope, elem, attrs) {
      scope.$watch(attrs['myToangularstr'], function (newVal) {
        if (typeof newVal !== 'undefined') {
          scope.val = newVal;
        }
      })
    }
  }
})

A working demo showing all three methods is here.

I think that is as close as one can get using the external API of angular.

musically_ut
  • 34,028
  • 8
  • 94
  • 106