【问题标题】:What is the correct way to access a service from an Angular template从 Angular 模板访问服务的正确方法是什么
【发布时间】:2014-06-14 07:35:08
【问题描述】:

我已经看到了两种方法来做到这一点。查看服务/控制器:

var app = angular.module('myApp', []);

app.service('user', function() {    
    this.loggedIn = false;
    this.logIn = function() { 
        this.loggedIn = true; 
    };
    this.logOut = function() {
        this.loggedIn = false;
    };
});

function Ctrl1($scope, user) {
    $scope.user = user;
}

function Ctrl2($scope, user) {
    $scope.loggedIn = user.loggedIn;

    // Proxy functions

    // This wont work because of binding:
    // $scope.logIn = user.logIn;
    // $scope.logOut = user.logOut;

    // This works
    $scope.logIn = function() {
        user.logIn();
    };
    $scope.logOut = function() {
        user.logOut(); 
    };

    // This also works:
    // $scope.logIn = user.logIn.bind(user);
    // $scope.logOut = user.logOut.bind(user);

    $scope.$watch(function() {
        return user.loggedIn;
    }, function(value) {
        $scope.loggedIn = value;
    });
}

还有 HTML:

<div ng-controller="Ctrl1">
    <h2>Ctrl1: Access the user service directly</h2>
    <div ng-show="user.loggedIn">
        Logged In
        <button ng-click="user.logOut()">Log Out</button>
    </div>
    <button ng-show="!user.loggedIn" ng-click="user.logIn()">Log In</button>    
</div>
<hr />
<div ng-controller="Ctrl2">
    <h2>Ctrl2: Proxy via the controller</h2>
    <div ng-show="loggedIn">
        Logged In
        <button ng-click="logOut()">Log Out</button>
    </div>
    <button ng-show="!loggedIn" ng-click="logIn()">Log In</button>  
</div>

直播:http://jsfiddle.net/h6AR4/

将服务直接添加到作用域感觉不对,但会导致控制器代码更简洁。

代理所有功能会导致控制器代码混乱。

是否有明确的“角度方式”?

【问题讨论】:

    标签: angularjs angularjs-scope angular-services


    【解决方案1】:

    您上面概述的方法是“支持”,因为您已将整个服务绑定到$scope。恕我直言,让您的模板“窥视”服务中定义的所有方法通常不是最好的(如果您愿意的话,我会将其标记为代码异味)。

    此外,调用 AngularJS 服务(不带代理方法)现在会使应用程序的实现更加耦合且更难测试。也就是说,在以下情况下,采用更精简的方法可能是有意义的:

    • 您的服务(和控制器)是轻量级和直通式的,而额外的开销(编写代理方法)是不值得的。
    • 测试(更重要的是,模拟)对您的用例不是很重要,或者代码很容易通过其他方法验证
    • 您的服务会立即返回数据(而不是延迟/承诺值)。延迟值需要一个控制器方法来处理“加载”状态以及解包 Promise 结果(当它可用时)。

    总的来说,这里是 YMMV,但没有明确的原因为什么直接绑定不是“正确”或“允许”。

    Pawel 有一篇很好的文章,提供了相同的选项,但社区中的共识也是,虽然它是一个选项,但这种绑定方法很少是“正确”的选项:https://stackoverflow.com/a/15040125/283788

    【讨论】:

      猜你喜欢
      • 2018-06-09
      • 1970-01-01
      • 2017-06-23
      • 2020-01-21
      • 1970-01-01
      • 1970-01-01
      • 2017-09-14
      • 1970-01-01
      • 2019-12-20
      相关资源
      最近更新 更多