i've this HTML:
<p>Hello {{name}}</p>
and the controller is:
function myCtrl(scope, service) {
scope.name = service.getUsername(); // service.getUsername() return "World!"
}
myCtrl.$inject = ['$scope', 'originalService'];
The service works fine, so i don't paste the code here... In this case the result is "Hello world!" I changed the HTML in this way:
<p>Hello {{service.getUsername()}}</p>
But this does not work.
I changed the controller:
function myCtrl(scope, service) {
scope.ser = service;
}
myCtrl.$inject = ['$scope', 'originalService'];
and then the HTML
<p>Hello {{ser.getUsername();}}</p>
This works!
So my question is:
Is this the only way to use the functions of a service directly in the HTML, or i'm missing something?
AngularJS templates can only invoke functions that are available on a scope. So, whatever approach you take you need to have your function on a scope.
If you want your service's functions to be directly invokable from a template you've got several options:
The one you've tried - that is, expose the whole service on a scope:
$scope.service = service;
and then in a template:
<p>Hello {{service.getUsername();}}</p>
This is one-liner in a controller and makes all the service methods available on a scope and thus to templates.
Expose methods one by one
to have precise control over what gets exposed:
$scope.getUsername = service.getUsername;
and then in a template:
<p>Hello {{getUsername();}}</p>
This requires more work exposing methods but gives you fine-grained control over what gets exposed.
Expose proxing methods:
$scope.getMyUsername = function() {
//pre/post processing if needed
return service.getUsername();
};
You can use any of those methods or mix and combine them but at the end of the day a function must end up on a scope (either directly or through another object exposed on a scope).