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

Bru*_*uno 28 javascript angularjs angularjs-service angularjs-scope

我有这个HTML:

<p>Hello {{name}}</p>
Run Code Online (Sandbox Code Playgroud)

控制器是:

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

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

<p>Hello {{service.getUsername()}}</p>
Run Code Online (Sandbox Code Playgroud)

但这不起作用.

我改变了控制器:

function myCtrl(scope, service) {
    scope.ser = service;
}
myCtrl.$inject = ['$scope', 'originalService'];
Run Code Online (Sandbox Code Playgroud)

然后是HTML

<p>Hello {{ser.getUsername();}}</p>
Run Code Online (Sandbox Code Playgroud)

这有效!

所以我的问题是:

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

pko*_*rce 61

AngularJS模板只能调用作用域上可用的函数.因此,无论采用何种方法,您都需要在示波器上使用您的功能.

如果您希望从模板直接调用您的服务功能,您可以选择以下几种方法:

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

$scope.service = service;
Run Code Online (Sandbox Code Playgroud)

然后在模板中:

<p>Hello {{service.getUsername();}}</p>
Run Code Online (Sandbox Code Playgroud)

这是控制器中的单行程序,并使范围上的所有服务方法都可用,因此也可用于模板.

一个接一个地暴露方法

准确控制暴露的内容:

$scope.getUsername = service.getUsername;
Run Code Online (Sandbox Code Playgroud)

然后在模板中:

<p>Hello {{getUsername();}}</p>
Run Code Online (Sandbox Code Playgroud)

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

公开代理方法:

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

您可以使用这些方法中的任何一种或混合它们,但在一天结束时,函数必须最终在作用域上(直接或通过作用域上公开的另一个对象).

  • 好答案.我会避免将整个服务对象添加到范围,如果它不是某种类型的视图服务,并且您的模板需要服务器的所有功能.您通常只想在模板所需的范围内添加数据/函数,仅此而已. (4认同)

Jua*_*uez 14

另一种方法:

在$ rootScope上公开服务:

$rootScope.service = service;
Run Code Online (Sandbox Code Playgroud)

然后在模板中:

<p>Hello {{service.getUsername();}}</p>
Run Code Online (Sandbox Code Playgroud)

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

  • 那很脏.我喜欢它 ! (8认同)