28

我有这个 HTML:

<p>Hello {{name}}</p>

控制器是:

function myCtrl(scope, service) {
    scope.name = service.getUsername(); // service.getUsername() return "World!"
}
myCtrl.$inject = ['$scope', 'originalService'];

该服务工作正常,所以我不在这里粘贴代码......在这种情况下,结果是“ Hello world! ”我以这种方式更改了 HTML:

<p>Hello {{service.getUsername()}}</p>

但这不起作用。

我改变了控制器:

function myCtrl(scope, service) {
    scope.ser = service;
}
myCtrl.$inject = ['$scope', 'originalService'];

然后是 HTML

<p>Hello {{ser.getUsername();}}</p>

这行得通!

所以我的问题是:

这是直接在 HTML 中使用服务功能的唯一方法,还是我遗漏了什么?

4

3 回答 3

61

AngularJS 模板只能调用作用域上可用的函数。所以,无论你采取什么方法,你都需要在一个范围内拥有你的功能。

如果您希望您的服务的功能可以直接从模板调用,您有几个选项:

您尝试过的那个 - 也就是说,在一个范围内公开整个服务

$scope.service = service;

然后在模板中:

<p>Hello {{service.getUsername();}}</p>

这是控制器中的单行代码,使所有服务方法在作用域上可用,从而对模板可用。

一一暴露方法

精确控制暴露的内容:

$scope.getUsername = service.getUsername;

然后在模板中:

<p>Hello {{getUsername();}}</p>

这需要更多的工作暴露方法,但可以让您对暴露的内容进行细粒度控制。

公开代理方法

$scope.getMyUsername = function() {
   //pre/post processing if needed 
   return service.getUsername();
};

您可以使用这些方法中的任何一种,也可以混合使用它们,但归根结底,函数必须以作用域结束(直接或通过作用域上暴露的另一个对象)。

于 2013-02-23T11:39:31.543 回答
14

Another way to do it:

Expose the service on $rootScope:

$rootScope.service = service;

and then in a template:

<p>Hello {{service.getUsername();}}</p>

You can do this on app.run, and you will get the service in all the views of your app. You could use this method for Authentication services.

于 2014-08-16T12:27:39.757 回答
1

在 $scope 中公开您的服务的另一种方法是向您的服务方法/数据对象添加一个函数指针。

scope.serviceData = service.data;
// Or
scope.getServiceData = service.getData;

在您的视图中,您可以使用括号来调用它。

<input ng-model="serviceData().key" />
// Or
<input ng-model="getServiceData().key" />
// Or
{{getServiceData().key}}

我个人喜欢这种方法,我目前正在使用它以使多个视图与相同的数据保持同步。它确实带来了一些问题,尽管如此处所述: AngularJS。关于来自服务的正确双向数据绑定的最佳实践

至于暴露大量数据,我目前正在尝试做这样的事情。

// Within your view.
{{getServiceDataByKey('key')}}

// In your controller.
scope.getServiceDataByKey = service.getServiceDataByKey;

// In your service.
getServiceDataByKey : function (key) {
   return dataObject[key];
}

我这样做的原因是我们希望保持控制器尽可能干净,并将所有数据集中在一个地方。此外,服务中的大多数数据都应该公开。

于 2013-08-19T19:03:47.880 回答