angularjs控制器在使用异步服务时不按顺序执行

时间:2014-10-13 23:36:22

标签: angularjs angularjs-scope angular-ui-router angularjs-controller

我无法找到在包含异步调用的控制器中使用局部变量的方法。有没有办法强制控制器顺序运行[至少一些]代码?

控制器:

angular.module('myApp.controllers.contacts', [])

.controller('CtrlContacts',
[       '$scope','apiUsers',
function($scope,  apiUsers){

    var selected = $scope.selected = [];

    apiUsers.getShortlist().then(function(response){

        // WILL correctly populate the associated view
        $scope.selected = response.data.data.contacts;

        // WILL NOT correctly populate the associated view
        selected = response.data.data.contacts;
        console.log(selected); // shows the correct data

    });
}

;

如果apiUser.getShortlist()不是异步调用,这可以正常工作。

我不介意这么多,但变量可能有点笨拙。此外,当偶尔的反应必须是“我不确定为什么,但做到这一点或角度会生气”时,试图对人进行交叉训练是一种痛苦。

======

修改

======

感谢Esteban和Greg。

将我选择的变量视为对象属性,就像虚拟对象一样。我实际上使用“controller as”语法,所以我最终编写了这样的控制器:

控制器:

angular.module('myApp.controllers.contacts', [])

.controller('CtrlContacts',
[       '$scope','apiUsers',
function($scope,  apiUsers){

    var self = this;
    var selected = $scope.selected = [];

    apiUsers.getShortlist().then(function(response){

        self.selected = response.data.data.contacts;

    });
}

;

1 个答案:

答案 0 :(得分:2)

这与角色生气无关'。这个引用如何在大多数编程语言中工作。要解决您的问题,您可以执行以下操作:

var selected = $scope.selected = [];

apiUsers.getShortlist().then(function(response){
    selected = $scope.selected = response.data.data.contacts;
});

替代:

var selected = $scope.selected = [];

apiUsers.getShortlist().then(function(response){
    // this will update the array itself:
    $scope.selected.splice(0, $scope.selected.length, response.data.data.contacts);
});

为什么需要更新selected变量
原因是selected指向您不期望它的数组。请参考以下示例代码:

var foo,
bar;

// foo && bar both will look this: [1] && [1]
foo = bar = [1];    

// foo && bar will look this: [1] && [1,2]
bar = [1,2];

你要改变的是bar的参考与foo不同。但是,如果更新基础数组,引用将保持不变,并且您的值将相同。一个例子:

var foo,
bar;

// foo && bar both will look this: [1] && [1]
foo = bar = [1];    

// foo && bar will look this: [1,2] && [1,2]
bar.push(2);