【问题标题】:AngularJS, $http.get() and "controller as"AngularJS、$http.get() 和“控制器作为”
【发布时间】:2015-07-26 07:56:19
【问题描述】:

我对整个 AngularJS 世界以及它的工作原理都很陌生,但是我正在努力让它按预期工作。我知道这与我使用 $http.get() 并尝试将变量分配回我的控制器的方式有关,但我就是想不通。

使用$scope 而不是this 我可以让它工作,但是如果可能的话,我更喜欢使用this 这样我可以使用“控制器作为”

代码:

app.controller('ctrlSuppliers', function($http){

    this.supplierList = {};

    $http.get("http://some_url_here")
            .success(function(response) {  this.supplierList = response.records;})
            .error(function() { this.supplierList = [{supplier_id: 0, supplier_name: 'Error Getting  Details'}];});
});

在此示例中,我无法从 HTML 页面内的 supplierList 中访问来自 $http.get 请求的任何结果(即 {{ supplier.supplierList[0].supplier_name }} 不显示任何结果)

我知道,如果我将控制器更改为 $scope,我可以访问该数据(尽管不使用与上述相同的格式),并且我也知道通过在 @ 内使用 console.log(this.supplierList) 填充数据987654331@电话。

我也知道它不起作用的原因是this 的上下文从控制器内部更改为$http.get 调用内部。

所以我的问题是:如何使用this 而不是scope 访问$http.xxx 调用的结果?我已经阅读了一些关于它的不同来源,但大多数都在谈论使用 $scope 和承诺。我没有找到任何使用this(或使用var supplier = this 声明)的内容。任何帮助将不胜感激。

谢谢,

【问题讨论】:

  • 请注意 $http 调用通常不属于您的控制器!将它们提取到服务中,以实现可重用性、稳定性和非无偿依赖注入。
  • @GrumbleSnatch 谢谢。正如我所说,我才刚刚开始研究 Angular,还没有时间浏览所有特性和功能,但是现在了解它可能会在我最终发现它们时为我节省大量时间

标签: javascript angularjs angularjs-http


【解决方案1】:

始终存储对 this 的变量引用,这样您就不会遇到上下文问题,然后在整个控制器中使用该变量而不是 this

app.controller('ctrlSuppliers', function($http){
    var vm = this;
    // now can forget using "this" and use variable instead
    vm.supplierList = {};

    $http.get("http://some_url_here") .success(function(response) {
         // no context issues since "vm" is in scope  
         vm.supplierList = response.records;
    });               
});

【讨论】:

  • 我确定我昨晚尝试了这种方法,但它对我不起作用,但是将 this 声明为一个变量并引用该变量现在正在工作。如此简单 - 非常感谢
  • 对于任何正在阅读本文的人来说,成功现在已被弃用。请改用 .then。
【解决方案2】:

对于$http,您可以选择将自己的对象存储在configObject 中,这是$http.get() 的可选第二个参数。然后,您可以使用此对象,因为它是 response 的属性。

如果您在循环中多次调用 $http.get(),此技术特别有用。

【讨论】:

    【解决方案3】:

    this 变量在 JavaScript 中很棘手。执行回调函数时,您将不知道 this 引用的是什么。除非它记录在某处。

    您必须使用.bind(this) 附加您自己的this 值才能在函数中使用。

    app.controller('ctrlSuppliers', function($http){
        this.supplierList = {};
        $http.get("http://some_url_here")
                .success(function(response) {
                     this.supplierList = response.records;
                }.bind(this))
                .error(function() { 
                     this.supplierList = [{supplier_id: 0, supplier_name: 'Error Getting  Details'}];
                }.bind(this));
    });
    

    参见绑定手册:

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

    【讨论】:

      【解决方案4】:

      使用 ecmascript 6 中可用的箭头函数,this 的问题得到了解决,您可以输入更少的内容。您的示例如下所示:

      app.controller('ctrlSuppliers', function($http){
          this.supplierList = {};
      
          $http.get("http://some_url_here")
                  .success(response => { this.supplierList = response.records; })
                  .error(() => { this.supplierList = [{supplier_id: 0, supplier_name: 'Error Getting  Details'}]; });
      });
      

      结果相当于将this存入一个变量,但更简洁。

      【讨论】:

        【解决方案5】:

        我认为 charlietfl 的答案是正确的,但认为稍微扩展的解释可能会有所帮助。

        "this" 在 javascript 中是指当前函数调用的上下文。如果您查看您的代码,您会发现它被用于两个函数 -

        app.controller('ctrlSuppliers', function($http){
        
            //first use of this - used in the context of the controller function
            //In this case, this = the controller
            this.supplierList = {};
        
            $http.get("http://some_url_here")
                    .success(function(response) {  
                        //second use of this - used in the context of the http success function callback
                        //this will likely not be the controller.  It's value depends on how the caller (the $http framework) invoked the method.
                        this.supplierList = response.records;
                     })
                     ....
        

        由于它们是两个不同的函数,它们可能具有完全不同的上下文,因此“this”将指代不同的对象(如您所见)。

        处理这个问题的标准方法是保存第一个函数的调用上下文以供其他函数使用。 @charlietfl 的回答是实现这一目标的好方法。我添加了他的代码以供参考。

        app.controller('ctrlSuppliers', function($http){
            var vm = this;
            vm.supplierList = {};
        
            $http.get("http://some_url_here")
                    .success(function(response) {  vm.supplierList = response.records;})
        });
        

        【讨论】:

          猜你喜欢
          • 2014-05-02
          • 2015-12-20
          • 2014-09-05
          • 2014-07-27
          • 2015-07-04
          • 1970-01-01
          • 2016-03-29
          • 2014-05-03
          • 1970-01-01
          相关资源
          最近更新 更多