在 AngularJS 中使用 .controller 方法时无法访问 $location

Posted

技术标签:

【中文标题】在 AngularJS 中使用 .controller 方法时无法访问 $location【英文标题】:Can't access $location when using .controller method in AngularJS 【发布时间】:2013-09-11 01:28:05 【问题描述】:

我在表单上使用 ng-submit 将数据推送到 Firebase,一切正常。我想做的是同时改变观点。在提交按钮本身上,我设置了 ng-click 以使用 $location 执行函数。如果我将 changeView 函数放在 .controller 方法中,我将无法使用 $location(具体来说,它说 - “错误:'undefined' 不是对象(评估 '$location.path')”)。任何帮助都是超级骗子。

// This doesn't work and throws the error
myApp.controller('CtrlName', ['$scope', 'angularFireCollection',
    function($scope, angularFireCollection, $location) 

         $scope.changeView = function(view) 
             $location.path(view);
         

    
]);



// This works as expected, but I'm name spacing my functions globally and I will have to change how I'm accessing my Firebase, which isn't really desired.   
function CtrlName($scope, angularFireCollection, $location) 

    $scope.changeView = function(view) 
        $location.path(view);
    


这是我的模板:

<form role="form" ng-submit="tactics.add(tactic)">
    <div class="form-group">
        <label>Select Method</label>
            <select class="form-control" ng-model="tactic.type">
                <option>Email</option>
                <option>Display</option>
            <option>SMS</option>
            <option>Print</option>
        </select>
    </div>
    <button type="submit" class="btn btn-success" ng-click="changeView('/my-tactics')">Save</button>
</form>

【问题讨论】:

两年后看到这篇文章,我不敢相信我正在这样做。对于任何爬行的人,不要这样做。这就是应许的用途。我应该做的是触发一个操作数据的函数,一旦完成,然后执行正确的重定向。这可以通过 $http、$q 甚至 Firebase 的 $save() 来完成。 【参考方案1】:

您没有将$location 对象注入您的控制器。它已在您的函数参数中列出,但您忘记在所述函数之前将其添加到列表中。

myApp.controller('CtrlName', ['$scope', 'angularFireCollection','$location',
    function($scope, angularFireCollection, $location) 
        ...
    ]);

【讨论】:

老兄,我发誓我试过了,但现在它正在工作。谢谢。虽然这现在正在扼杀我的表单提交。您的回答是正确的,所以我会这样标记,但我认为执行此操作的最佳方法是避免有两个单独的事件。重构... 很高兴我能帮上忙。您的其他问题可能归因于您在表单标记中使用ng-submit,但提交按钮中的ng-click 正在“优先”,因为它实际上更改了您的URL 路径。它可能不会优先,但它肯定会在您提交表单之前或之后更改您的 URL/视图。【参考方案2】:

天哪,我不敢相信我曾经这样做过。 #捂脸。这是重定向表单提交的正确方法。

模板

<form role="form" ng-submit="vm.submit(tactic)">
    <div class="form-group">
        <label>Select Method</label>
            <select class="form-control" ng-model="tactic.type">
                <option>Email</option>
                <option>Display</option>
            <option>SMS</option>
            <option>Print</option>
        </select>
    </div>
    <button type="submit" class="btn btn-success">Save</button>
</form>

控制器

angular.module('MyApp')
  .controller('CtrlName', function($scope, $location, $log, angularFireCollection, tactics) 

  var vm = this;

  vm.submit = function submit(item) 

    tactics.add(item)
      .then(function(rsp) 
        $log.debug('Attempted to add tactic to Firebase', rsp);
        $location.path('/my-tactics');
      );

  ;

  
);

显着变化:

    我没有为我的 DI 使用注释,我将其卸载到 ng-annotate,这样可以缓解我最初提出这个问题时遇到的任何问题。 我正在使用在提出这个问题时不存在的“controller as”语法。 我不再通过尝试在两个单独的函数中对可能的一个事件执行两个单独的操作来创建一些奇怪的竞争条件。 Promise 是此类操作的完美解决方案。

【讨论】:

【参考方案3】:

也不要忘记在你的操作中添加 $location:

authControllers.controller('AuthRegisterCtrl', ['$scope', '$http', '$location',

function ($scope, $http, $location) 

    $scope.master = ;

    $scope.save = function (user) 
        $scope.master = angular.copy(user);
        $http(
            method: 'POST',
            url: '/angular/auth/register',
            data: user
        ).success(function (d) 
             $location.path('/login');

        );
    ;
]);

【讨论】:

注意:一定要在第一行加上'$location',在第三行加上$location。花了大约15分钟,因为我错过了第三行:function ($scope, $http, $location)

以上是关于在 AngularJS 中使用 .controller 方法时无法访问 $location的主要内容,如果未能解决你的问题,请参考以下文章

Angularjs[21] - 控制器的合理使用

AngularJS自定义Directive中link和controller的区别

AngularJS $http:当凭据标志为真时,不能在 Access-Control-Allow-Origin 中使用通配符

AngularJS 中 Controller 之间的通信

AngularJs学习笔记(慕课网)

angularJS实现不同视图同步刷新