【问题标题】:How do I inject $cookies into an AngularJS service?如何将 $cookies 注入 AngularJS 服务?
【发布时间】:2016-01-19 11:34:43
【问题描述】:

我阅读了$cookies at this link 的文档,它建议使用以下语法注入$cookies

angular.module('cookiesExample', ['ngCookies'])
   .controller('ExampleController', ['$cookies', function($cookies) {

因此,我尝试使用以下语法将 $cookies 注入服务(请注意以下 factory 而不是 controller

angular.module('auth', ['ngCookies'])
     .factory( 'auth', '$cookies',  function($rootScope, $http, $location, $cookies) {  

但结果是 FireFox 中出现了一个模糊的编译错误,导致应用无法编译。错误是在angular-bootstrap.js 中包含数万个字符,并且无法访问,因为angular-bootstrap.js 被压缩为每行可能包含 10,000+ 个字符的 20 行。由于angular-bootstrap.js 没有被修改,我假设错误出现在我的应用程序代码中,上面显示了唯一更改的行。

然后我通过尝试以下注入 $cookies 的语法解决了编译错误:

angular.module('auth', ['ngCookies'])
   .factory( 'auth', function($rootScope, $http, $location, $cookies) {  

结果是 FireFox 给出了一个不同的编译错误,指出 $cookies.get 不是函数,在以下代码行触发:

authenticated1 : $cookies.get('AUTH1'),

对我来说,这表明 $cookies 没有正确插入。

最后,我在angular-bootstrap.js 内部进行了关键字搜索,并确认有很多单词cookies 的实例,这意味着cookies api 在类路径中的那个文件中,因此问题出在似乎在用于将其插入服务的语法中。

那么我要对上面的代码进行哪些具体更改才能将$cookies api 正确注入auth 服务?


持续努力:


根据@charlietfl 和@KenDev 的建议,我尝试对服务第一行的语法进行两项更改。这两个版本都会导致编译错误,指出$cookies.get is not a function。为了消除混淆,我将实际服务模块中的所有代码粘贴如下:

//angular.module('auth', ['ngCookies']).factory( 'auth', [ '$cookies', function($rootScope, $http, $location, $cookies) {
angular.module('auth', ['ngCookies']).factory('auth', ['$rootScope', '$http', '$location', '$cookies', function($rootScope, $http, $location, $cookies){
        var auth = {

            authenticated1 : $cookies.get('AUTH1'),
            authenticated2 : $cookies.get('AUTH2'),
            usrname : '',

            loginPath : '/login',
            logoutPath : '/logout',
            homePath : '/checkpin',
            path : $location.path(),

            authenticate1 : function(credentials, callback) {

                var headers = credentials && credentials.username ? {
                    authorization : "Basic " + btoa(credentials.username + ":" + credentials.password)
                } : {};

                $http.get('user', {
                    headers : headers
                }).success(function(data) {
                    if (data.name) {
                        auth.authenticated1 = $cookies.get('AUTH1');
                    } 
                    else { 
//                          $cookies.put('AUTH1', 'no');
                        auth.authenticated1 = 'no';//$cookies.get('AUTH1'); 
                    }
                    callback && callback(auth.authenticated1);
                }).error(function() {
//                      $cookies.put('AUTH1', 'no');
                    auth.authenticated1 = 'no';//$cookies.get('AUTH1');
                    callback && callback(false);
                });

            },

            authenticate2 : function(funcJSON, callback) {
                $http.post('/check-pin', funcJSON).then(function(response, $cookies) {
                    if(response.data.content=='pinsuccess'){
                        auth.authenticated2 = $cookies.get('AUTH2');
                        callback && callback(auth.authenticated2);
                    }else {
//                          $cookies.put('AUTH2', 'no');
                        auth.authenticated2 = 'no';//$cookies.get('AUTH2'); 
                        callback && callback(false);
                    }
                });
            },

            clear : function() {
                $location.path(auth.loginPath);
//                  $cookies.put('AUTH1', 'no');
                auth.authenticated1 = 'no';//$cookies.get('AUTH1'); 
//                  $cookies.put('AUTH2', 'no');
                auth.authenticated2 = 'no';//$cookies.get('AUTH2'); 

                $http.post(auth.logoutPath, {}).success(function() { console.log("Logout succeeded");
                }).error(function(data) { console.log("Logout failed"); });
            },

            init : function(homePath, loginPath, logoutPath) {

                auth.homePath = homePath;
                auth.loginPath = loginPath;
                auth.logoutPath = logoutPath;

            }
        };
        return auth;
    }]);

请注意,我在以下第一行中分别尝试了上述两次:

angular.module('auth', ['ngCookies']).factory( 'auth', [ '$cookies', function($rootScope, $http, $location, $cookies) {

and then separately:  

angular.module('auth', ['ngCookies']).factory('auth', ['$rootScope', '$http', '$location', '$cookies', function($rootScope, $http, $location, $cookies){

然后我尝试了@gnerkis 的建议来更新 AngularJS 的版本。我注意到我的pom.xmlorg.webjars:angularjs1.3.8 版本,所以我在maven Central 中查找了最新版本,并在我的pom.xml 中将版本更改为1.4.8,然后输入mvn clean install -Umvn clean package -U紧随其后的是java -jar pathto/nameofjar.jar,但得到一个不同的编译错误,指出angular 未定义,并指向应用程序中每个控制器的第一个单词。然后,当我将应用程序恢复为1.3.8 时,我能够重新创建此正在进行的研究 部分开头所述的@charlietfl 和@KenDev 错误。

我还能尝试什么?

根据@gnerkus 的建议,我将index.html 发布如下:

<!doctype html>
<html>
<head>
<base href="/" />
<link href="css/angular-bootstrap.css" rel="stylesheet">
<style type="text/css">
[ng\:cloak], [ng-cloak], .ng-cloak {
    display: none !important;
}
</style>
</head>

<body ng-app="hello" ng-cloak class="ng-cloak">
    <div ng-controller="navigation" class="container">
        <ul class="nav nav-pills" role="tablist">
            <li ng-class="{active:tab('home')}"><a href="/">home</a></li>
            <li ng-class="{active:tab('message')}"><a href="/message">message</a></li>
            <li ng-class="{active:tab('public1')}"><a href="/public1">public1</a></li>
            <li ng-class="{active:tab('public2')}"><a href="/public2">public2</a></li>
            <li ng-class="{active:tab('public3')}"><a href="/public3">public3</a></li>
            <li ng-class="{active:tab('public4')}"><a href="/public4">public4</a></li>
            <li ng-class="{active:tab('register')}"><a href="/register">register</a></li>
            <li><a href="/login">login</a></li>
            <li ng-show="authenticated2()"><a href="" ng-click="logout()">logout</a></li>
        </ul>
    </div>
    <div ng-view class="container"></div>
    <script src="js/angular-bootstrap.js" type="text/javascript"></script>
    <script src="js/auth/auth.js" type="text/javascript"></script>
    <script src="js/home/home.js" type="text/javascript"></script>
    <script src="js/message/message.js" type="text/javascript"></script>
    <script src="js/public1/public1.js" type="text/javascript"></script>
    <script src="js/navigation/navigation.js" type="text/javascript"></script>
    <script src="js/hello.js" type="text/javascript"></script>
</body>
</html>

【问题讨论】:

  • 您为控制器和工厂执行的方式之间存在非常明显的语法差异。提示...controller()factory() 各有 2 个参数
  • @charlietfl factory 代码工作直到我尝试注入cookies。我仍在学习 AngularJS,并且犹豫要修复没有损坏的东西。但是尝试注入$cookies 破坏了它。
  • 因为缺少大括号...看看差异...控制器语法正确...使工厂语法匹配。 factory() 有 3 个参数而不是两个
  • @charlietfl 请参阅我添加到 OP 末尾的代码,显示尝试您的建议的结果。还有其他意见吗?
  • @CodeMed,在 angular 1.3.x 中尝试使用 var favoriteCookie = $cookies['AUTH1'];

标签: javascript angularjs twitter-bootstrap cookies dependency-injection


【解决方案1】:

这可能是angular 的旧版本造成的。在ngCookies 的文档中,我们有这一行:

在 Angular 1.3 之前,$cookies 公开了表示当前浏览器 cookie 值的属性。在 1.4 版本中,这种行为发生了变化,现在 $cookies 提供了一个标准的 getter、setter 等 API。

【讨论】:

  • 我将pom.xml中的org.webjars:angularjs的版本从之前的1.3.8改为1.4.8,然后输入mvn clean install -Umvn clean package -U,然后用新的创建了 jar,但结果是不同的 FireFox 编译错误 ReferenceError: angular is not defined 在应用程序中每个控制器的以下代码行:angular.module('auth', ...。有什么建议吗?
  • 我想不到。我对maven不太了解。页面上的脚本是如何加载的?你能给我看一个代码示例吗?
  • 我知道如何使用 firefox 调试器。有没有办法可以从中提取代码?或者我应该发布index.html,它将所有脚本加载到如下标签中:&lt;script src="js/angular-bootstrap.js" type="text/javascript"&gt;&lt;/script&gt;
  • 你可以发index.html
  • 我刚刚发布了index.html
【解决方案2】:

您没有将依赖项正确地注入到您的服务中。

angular.module('auth', ['ngCookies']).factory( 'auth', '$cookies',  function($rootScope, $http, $location, $cookies) {}

应该是

angular.module('auth', ['ngCookies']).factory('auth', ['$rootScope', '$http', '$location', '$cookies', function($rootScope, $http, $location, $cookies){}])

注意依赖参数的顺序如何匹配作为字符串提供的函数注释。还要注意括号。

在 Angular 文档中查看此页面,特别注意 Note on Minification

编辑, 在 Angular 1.3.x 中使用此语法获取和设置 cookie

 var storedCookie = $cookies['key']; // get
 $cookies['key'] = 'something'; // set

【讨论】:

  • 请参阅我添加到我的 OP 末尾的代码,显示您的建议结果。
  • 谢谢。我在对 OP 的评论中添加的 sn-p 可以让事情继续进行,而不会出现编译错误。我需要考虑一夜之间。我现在在这里已经很晚了。
猜你喜欢
  • 2016-12-09
  • 1970-01-01
  • 2014-02-08
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
  • 2014-01-27
  • 2017-01-07
相关资源
最近更新 更多