AngularJS,$ http.get()和"控制器为"

时间:2015-05-14 15:54:10

标签: javascript angularjs angularjs-http

我对整个AngularJS世界及其运作方式都很陌生,但是我很难让它按预期工作。我知道这与我使用$http.get()的方式有关,并试图将变量分配给我的控制器,但我无法弄清楚。

使用$scope代替this我可以使其正常运行,但如果可能的话,我更愿意使用this,因此我可以使用"控制器作为& #34;

代码:

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页面中$http.get内的supplierList请求中的任何结果(即{{ supplier.supplierList[0].supplier_name }}不显示任何结果)

我知道如果我将控制器更改为$scope我可以访问该数据(虽然不使用与上面相同的格式),并且我也知道使用{{1}填充数据在console.log(this.supplierList)电话里面。

我也知道它不起作用的原因是因为.success的上下文从控制器内部变为this调用。

所以我的问题是:如何使用$http.get代替this来访问$ http.xxx调用的结果?我已经阅读了几个不同的来源,但大多数人都在谈论使用scope和承诺。我没有找到使用$scope覆盖的任何内容(或使用this声明)。任何帮助将不胜感激。

谢谢,

5 个答案:

答案 0 :(得分:9)

始终存储对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;
    });               
});

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

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));
});

参见bind manual:

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

答案 3 :(得分:2)

使用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存储到变量中,但更简洁。

答案 4 :(得分:1)

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

javascript中的“this”是指当前函数调用的上下文。如果你查看代码,你会发现它在两个函数中使用 -

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;})
});