Javascript 我应该如何在不使用作用域的情况下引用控制器函数中的服务?

Javascript 我应该如何在不使用作用域的情况下引用控制器函数中的服务?,javascript,angularjs,angularjs-scope,angularjs-service,Javascript,Angularjs,Angularjs Scope,Angularjs Service,在阅读了几篇关于避免范围汤和参考建筑控制器的文章之后,我留下了一个紧迫的问题。我应该如何引用我的文档 控制器中的依赖关系 到目前为止,我的方法是将服务放在我的对象上,但我对此并不满意,因为现在我的服务暴露于外部世界(模板标记)。 在不直接引用$scope的情况下构建控制器的正确方法是什么,并使我的注入依赖项可供控制器使用,但不公开 正如您在下面看到的,我的工作是在“this”上添加$http,然后在原型中引用它 功能。由于上述原因,这不是我理想的选择 DOCTYPE html> {{txtCt

在阅读了几篇关于避免范围汤和参考建筑控制器的文章之后,我留下了一个紧迫的问题。我应该如何引用我的文档 控制器中的依赖关系

到目前为止,我的方法是将服务放在我的对象上,但我对此并不满意,因为现在我的服务暴露于外部世界(模板标记)。 在不直接引用$scope的情况下构建控制器的正确方法是什么,并使我的注入依赖项可供控制器使用,但不公开

正如您在下面看到的,我的工作是在“this”上添加$http,然后在原型中引用它 功能。由于上述原因,这不是我理想的选择

DOCTYPE html>
{{txtCtrl.greeting}
取名字

{{txtCtrl.names | json} var textController=函数($http){ this.greeting=“Hello World”; 这个。$http=$http; } textController.prototype.alert=函数(){ 警惕(这是问候语); } /*从//filltext.com检索测试数据*/ textController.prototype.getData=函数(){ var=这个; 这是$http({ 方法:“GET”, 网址:'http://www.filltext.com/?rows=10&fname={firstName}&lname={lastName}' }) .成功(功能(数据){ 名称=数据; }) .error(); } 角度模块(“应用程序”,[]) .controller(“textController”,textController); 引导(文档,[“应用程序]);


一种方法是使用IIFE创建一个闭包变量,并将
http服务的引用保持在控制器外部,然后在控制器中使用它

  (function(){
      var _$http; //<-- Here a private  variable

     ......

      /*retrieve test data from //filltext.com*/
      textController.prototype.getData = function(){
        var that = this;

       _$http({ //<-- Use it
          method: 'GET', 
          url: 'http://www.filltext.com/?rows=10&fname={firstName}&lname={lastName}' })...
         //...
      }

      angular.module("app").controller("textController",textController);

 })();
 var textController = function(userSvc){
    this.greeting="Hello World";
    this.userSvc = userSvc;
  }

....

  /*retrieve test data from //filltext.com*/
  textController.prototype.getData = function(){
    var that = this;
     //Call service with argument
    this.userSvc.getUsers({firstName:$scope.fn, lastName:$scope.ln}).success(function(data){
      that.names=data;
    })...;
  }

 ....
  angular.module("app").controller("textController",['UserService', textController]);

但是,我将只负责进行ajax调用和任何到服务的数据映射:-

例如:-

  angular.module("app").service('UserService', ['$http', function($http){
       this.getUsers = function(searchObj){ //Get the input and set your url
        return $http({
          method: 'GET', 
          url: 'http://www.filltext.com/?rows=10',
          params: searchObj  //<-- Pass params
        });

       }
   }]);

我想你可能想得太多了。如果需要从(视图)html访问getData(),则应将其附加到作用域

在您的用例中,我将使用注入器手册在闭包中保留对$http的引用

 var $http = angular.injector(['ng']).get('$http');
。 这样,您就可以将私人物品保存在控制器中

  (function(){
      var _$http; //<-- Here a private  variable

     ......

      /*retrieve test data from //filltext.com*/
      textController.prototype.getData = function(){
        var that = this;

       _$http({ //<-- Use it
          method: 'GET', 
          url: 'http://www.filltext.com/?rows=10&fname={firstName}&lname={lastName}' })...
         //...
      }

      angular.module("app").controller("textController",textController);

 })();
 var textController = function(userSvc){
    this.greeting="Hello World";
    this.userSvc = userSvc;
  }

....

  /*retrieve test data from //filltext.com*/
  textController.prototype.getData = function(){
    var that = this;
     //Call service with argument
    this.userSvc.getUsers({firstName:$scope.fn, lastName:$scope.ln}).success(function(data){
      that.names=data;
    })...;
  }

 ....
  angular.module("app").controller("textController",['UserService', textController]);
编辑:刚刚注意到这与@PSL解决方案类似。对不起,我没有注意到他的第一个解决方案。 然而,我带来了手动注射器,所以如果你同意的话,我保留这个答案!
EDITEDIT:更新了plunker,使其更易于测试。

这绝对更干净。我更喜欢我目前的解决方案。“我将等待其他用户(如果)加入,但这看起来像是一个赢家。”麦卡因茨补充道。然而,任何人都可以使用angular.injector获得
http
引用。看看这两种方法,我想我更喜欢构造函数方法,但我很好奇你会利用哪种方法?@mccainz我使用typescript,所以在使用第一种方法时,它会变得更丑陋,所以我总是将它附加到控制器实例上,但我不使用控制器作为语法,而是编写了一个语法糖,用于将函数和属性引用从控制器实例复制到范围。但我想我不会太担心。因为如果您真的想,您可以使用angular.injector始终获得http引用。@mccainz更新了有关如何在使用显式注释缩小依赖关系时处理依赖关系的详细信息的答案Nopes Op讨论的是附加到控制器实例的
$http
,而控制器实例又附加到作用域名为控制器别名的via属性。不,我只是在手动使用它。我不会注入一个不需要它的控制器,这样我就在一个我需要它的闭包中注入它。这就是为什么,你错过了依赖注入的要点:)我不喜欢在依赖子系统可用时绕过它,但在查看代码时会想到一点。您的方法将适用于缩小。我当前的方法在这方面会不会中断?我将更新示例,使其使用默认的喷油器系统@PSL,我测试我的控制器。注入一个mock确实有些困难。我将更新我的答案;)@如果使用适当的依赖注入模式,您的方法不会中断。i、 e
angular.module(“app”).controller(“textController”,“['$http',textController])
还有控制器aproact,您可以注入依赖项,如
textController.$inject=['$http','blah']
这是一种有文档记录的建议方式,使用injector注入依赖项是一种黑客行为(或者在某些情况下,由于设计问题,您可能会被阻止对其进行黑客行为,以避免循环引用)。
 var textController = function(userSvc){
    this.greeting="Hello World";
    this.userSvc = userSvc;
  }

....

  /*retrieve test data from //filltext.com*/
  textController.prototype.getData = function(){
    var that = this;
     //Call service with argument
    this.userSvc.getUsers({firstName:$scope.fn, lastName:$scope.ln}).success(function(data){
      that.names=data;
    })...;
  }

 ....
  angular.module("app").controller("textController",['UserService', textController]);
 var $http = angular.injector(['ng']).get('$http');