AngularJS,这种使用服务的方式好吗?

时间:2013-02-23 11:10:51

标签: javascript angularjs angularjs-scope angularjs-service

我有这个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中使用服务功能的唯一方法,还是我遗漏了什么?

3 个答案:

答案 0 :(得分: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();
};

你可以使用这些方法中的任何一种,或者混合和组合它们,但是在一天结束时,一个函数必须最终在一个范围(直接或通过范围上公开的另一个对象)。

答案 1 :(得分:14)

另一种方法:

在$ rootScope上公开服务

$rootScope.service = service;

然后在模板中:

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

您可以在app.run上执行此操作,您将在应用的所有视图中获得该服务。您可以将此方法用于身份验证服务。

答案 2 :(得分: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. Best practice concerning proper two way data binding from a service

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

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

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

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

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