从Angular模板访问服务的正确方法是什么

时间:2014-04-28 16:32:30

标签: angularjs angularjs-scope angular-services

我已经看到了两种方法。请参阅服务/控制器:

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/

将服务直接添加到范围感觉不对,但会产生更清晰的控制器代码。

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

是否有确定的'Angular方式'?

1 个答案:

答案 0 :(得分:1)

您上面列出的方法是&#34; 支持&#34;从某种意义上说,您已将整个服务绑定到$scope。恕我直言,它通常不是最好的(如果你愿意的话,我将它标记为代码味道)让你的模板&#34;偷看&#34;进入服务中定义的所有方法。

此外,调用AngularJS服务(不使用代理方法)现在使测试应用程序的实现变得更加耦合和困难。也就是说,如果符合以下条件,可以采用更精简的方法:

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

总的来说,YMMV在这里但是没有明确的理由为什么直接绑定不是&#34;#34;正确&#34;或者&#34;允许&#34;。

Pawel有一个很好的写作,提供相同的选项,但社区的共识也是,虽然它是一个选项,但它很少&#34;权利&#34;使用此绑定方法的选项:https://stackoverflow.com/a/15040125/283788