Javascript $scope变量值未在控制器中更新?

Javascript $scope变量值未在控制器中更新?,javascript,angularjs,Javascript,Angularjs,下面添加了我的控制器代码。我想访问$scope.FCGId的值。。。。。。。如何访问此变量 angular.module('hotelApp.controllers') .controller('menuCtrl', ['$scope','menu' function($scope,'menu') { $scope.categories = []; $scope.FCGId = 0 $

下面添加了我的控制器代码。我想访问$scope.FCGId的值。。。。。。。如何访问此变量

 angular.module('hotelApp.controllers')
     .controller('menuCtrl', ['$scope','menu'
         function($scope,'menu') {

             $scope.categories = [];
             $scope.FCGId = 0

             $scope.items = [];

             $scope.getCategories = function() {
                 menu.getCategories().success(function(data) {
                     $scope.categories = data;
                     $scope.FCGId = data['rows'][0].GRPCOD;

                 });
             }

             $scope.getItems = function(gropuId) {
                 menu.getItems(gropuId).success(function(data) {
                     $scope.items = data;
                     console.log(data);
                 });
             }

             $scope.$on('$ionicView.afterEnter', function() {
                 $scope.getCategories();
                 console.log($scope.FCGId);
                 $scope.getItems($scope.FCGId);

             });
         }
     ]);

从中,上述代码返回0,而不是在getCategories()函数中更新的值

之所以会出现问题,是因为javascript几乎总是比异步调用返回的速度快,所以您的
$scope.getItems
总是在
$scope.getCategories
返回之前调用

要严格地对API调用进行排序,您需要一个名为promise的强大构造。那里应该有很多资源,只要谷歌“角度承诺”,你就很好了=)


编辑:实际使用success函数是最直接的方法

$scope.getCategories = function() {
    menu.getCategories().success(function(data) {
        $scope.categories = data;
        $scope.FCGId = data['rows'][0].GRPCOD;

        $scope.getItems($scope.FCGId);  // to here
    });
}

$scope.getItems = function(gropuId) {
    menu.getItems(gropuId).success(function(data) {
        $scope.items = data;
        console.log(data);
    });
}

$scope.$on('$ionicView.afterEnter', function() {
    $scope.getCategories();
    console.log($scope.FCGId);
    // $scope.getItems($scope.FCGId);  // move this line
});
通过这种方式,你不必处理所有那些$q和$d。并承诺反模式。

很好

$scope.getCategories函数正在进行异步调用 在以下事件中

$scope.$on('$ionicView.afterEnter', function() {
                 $scope.getCategories();
                 console.log($scope.FCGId);
                 $scope.getItems($scope.FCGId);

             });
调用$scope.getCategories()时,会给出此异步调用

但脚本并没有等待那个调用的完成。以及console.log($scope.FCGId)中的脚本访问$scope.FCGId变量没有初始化,因为异步cal未完成

这个问题的解决办法

您可以在控制器开始时调用$scope.getCategories函数作为初始化部分 或者您应该从$scope.getCategories函数返回promise 或者根据您的要求以另一种方式使用承诺

编辑代码

定义$scope.getCategories如下

控制器中的inejct$q

var defer = $q.defer();       
$scope.getCategories = function() {
                 menu.getCategories().success(function(data) {
                    $scope.categories = data;
                   // $scope.FCGId = data['rows'][0].GRPCOD;
                    defer.resolve(data['rows'][0].GRPCOD);  
                    return defer.promise;

                 });
             }  
并以这种方式进行事件处理

 $scope.$on('$ionicView.afterEnter', function() {
                 $scope.getCategories().then(function(successData){
                 $scope.FCGId = successData
                  console.log($scope.FCGId);
                 });

                 $scope.getItems($scope.FCGId);

             });    
解决方案-2。 调用$scope.getCategories函数时也没有依赖关系 所以你可以在主计长开始时调用它


您可以对调用$scope执行相同的操作。getItems

看起来像您的菜单。getCategories()是一个异步执行块,由于延迟执行,因此$scope.FCGId的值为0

您可以将函数作为第二个参数传递给getCategories函数,该函数将被执行并执行必要的赋值和进一步的调用

$scope.setFCGValue = function(data) {
     $scope.categories = data;
     $scope.FCGId = data['rows'][0].GRPCOD;
     $scope.getItems($scope.FCGId);
};

$scope.$on('$ionicView.afterEnter', function() {
     menu.getCategories().success($scope.FCGValue);
});

我们正在做的是传递自定义函数,该函数将在getCategories()部分之后执行。

所有这些代码都属于同一个控制器吗?是的。。从同一个控制器你需要在哪里访问它?你说的是HTML吗?似乎是时间问题。当您调用日志时,是否确定变量中填充了
getCategories()
函数的结果数据?如果在
getCategories()
和/或
getItems()
中为
$scope.FCGId
添加控制台日志,您会得到什么?但它与$scope.on中的整个函数相同,但我不想改变结构,也不希望结果是可能的?然后你们应该看看AngularJs$q的延迟API,但它和我们在$scope.on中的整个函数是一样的,但我不想改变结构,也不想看到可能的结果?我认为应该在函数内部声明defer,并在ajax调用启动后立即返回承诺(也就是在成功之外)。是的,@lcycool,var defer可以在函数外部和函数内部声明,我们可以定义这个变量defer=$q.defer();你能给我看一个在函数外声明defer的例子吗$scope.getCategories=function(){menu.getCategories().success(函数(数据){$scope.categories=data;defer=$q.defer()//$scope.FCGId=data['rows'][0]。GRPCOD;defer.resolve(数据['rows'][0]。GRPCOD);return defer.promise;});}是的,使用promise它是可能的,但它与$scope.on中的整个函数相同,但我不想更改结构,并且希望结果是可能的?结构略有更改