Angularjs $scope变量在函数内设置时未定义

Angularjs $scope变量在函数内设置时未定义,angularjs,angularjs-scope,Angularjs,Angularjs Scope,我的学习应用程序中有以下示例代码。该服务完成了他的工作,并使用php生成的json代码从页面中提取一些数据,目前为止效果良好 服务: (function() { 'use strict'; angular .module('app.data') .service('DashboardService', DashboardService); DashboardService.$inject = ['$http']; functio

我的学习应用程序中有以下示例代码。该服务完成了他的工作,并使用php生成的json代码从页面中提取一些数据,目前为止效果良好

服务:

(function() {
    'use strict';

    angular
        .module('app.data')
        .service('DashboardService', DashboardService);

    DashboardService.$inject = ['$http'];
    function DashboardService($http) {

        this.getFormules = getFormules;

        ////////////////

        function getFormules(onReady, onError) {
            var formJson = 'server/php/get-formules.php',
                formURL  = formJson + '?v=' + (new Date().getTime()); // Disables cash

            onError = onError || function() { alert('Failure loading menu'); };

            $http
                .get(formURL)
                .then(onReady, onError);
        }

    }
})();
    dataLoader.getFormules(function (items){

        $scope.formuleItems = items.data;

    });

    console.log('+++++++++++++++++', $scope.formuleItems); // gives undefined
然后我调用控制器中的getFormules函数,将所有数据放入$scope.formuleItems中,并测试是否所有操作都成功,以及“否”<代码>$scope.formuleItems=未定义-奇怪,因为我的视图正在显示数据

控制器的一部分:

(function() {
    'use strict';

    angular
        .module('app.data')
        .service('DashboardService', DashboardService);

    DashboardService.$inject = ['$http'];
    function DashboardService($http) {

        this.getFormules = getFormules;

        ////////////////

        function getFormules(onReady, onError) {
            var formJson = 'server/php/get-formules.php',
                formURL  = formJson + '?v=' + (new Date().getTime()); // Disables cash

            onError = onError || function() { alert('Failure loading menu'); };

            $http
                .get(formURL)
                .then(onReady, onError);
        }

    }
})();
    dataLoader.getFormules(function (items){

        $scope.formuleItems = items.data;

    });

    console.log('+++++++++++++++++', $scope.formuleItems); // gives undefined
我做的第一件事是在stackoverflow上搜索,看看是否有其他人也有同样的问题,结果是:

我知道有一些解决方法,我已经做了自己的研究,但有些东西告诉我,这(见下面的例子)不是解决这个问题的最佳方法

解决方案一:将$watch放入控制器中

甚至:

if($scope.formuleItems != null) {}

控制器的其余部分依赖于$scope.formuleItems。我真的必须把所有东西都放进
$watch
如果
?我可以用承诺来解决这个问题吗?我以前从未这样做过,因此希望能得到一些帮助。

您回调中的代码

function (items){
    $scope.formuleItems = items.data;
}
是异步计算的。这意味着您首先触发请求,然后javascript继续执行代码行,从而执行

console.log('+++++++++++++++++', $scope.formuleItems); // gives undefined
此时还没有调用回调,因为这需要一些时间,并且随时都可能发生。没有为此停止执行。 因此,$scope.formuleItems的值当然仍然没有定义

之后-在未来的某个未定义的时间(可能几毫秒后),将调用回调并更改$scope.formuleItems的值。您必须在回调函数中记录该值


如果您想在JavaScript中取得成功,您迫切需要理解这个概念,因为这种情况会反复发生:)

JavaScript是异步运行的。在登录到控制台之前,如何知道设置该值的函数正在运行?有一个很好的问题涉及到这一点,但我目前找不到。然而,这正是你需要了解的。发现它:我建议你阅读,其中描述了你陷入的关于角度承诺的两个陷阱:不理解异步,传递回调函数,而不是不传递任何东西并返回承诺。哇,JB Nizet,多么棒的教程!让我们把这本书收起来,读几遍,直到我真正理解为止。