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

使用异步服务时angularjs控制器未按顺序执行,angularjs,angularjs-scope,angular-ui-router,angularjs-controller,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.ge

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

控制器:

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

    });
}

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

    });
}

;
如果apiUser.getShortlist()不是一个异步调用,那么它就可以正常工作

我不介意这么多,但变量可能会变得有点笨拙。此外,当偶尔的回答是“我不知道为什么,但是去做吧,否则你会生气”时,试图交叉训练别人是一种痛苦

=========

编辑

=========

谢谢埃斯特班和格雷格

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

控制器:

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

    });
}

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

    });
}

;

这与“生气”无关。这就是大多数编程语言中引用的工作方式。要解决问题,您可以执行以下操作:

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);
});
为什么需要更新所选的
变量

原因是所选的
指向一个您不希望它出现的数组。以下面的示例代码为例:

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

要从视图中访问任何内容,它必须位于
$scope
范围内。很难说出你在问什么。您是否希望视图能够访问不属于
$scope
的变量?在第一个解决方案中,为什么第一行不保存.then()块可用于填充scope的引用?@user3822241,因为您正在重新定义所选的局部变量
等于什么,它将不再指向与
$scope.selected
属性相同的对象。这意味着它们不再是同一个意思。因此,您必须将结果分配回两者以保持它们同步。@user3822241 Greg是正确的,您正在更改变量的引用,而不是基础数组本身。如果你看看我更新的答案,它能更好地解释发生了什么。