Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript angularjs don'中的承诺;行不通_Javascript_Angularjs - Fatal编程技术网

Javascript angularjs don'中的承诺;行不通

Javascript angularjs don'中的承诺;行不通,javascript,angularjs,Javascript,Angularjs,我有一个从后端获取数据的工厂: as.factory("abbdata", function GetAbbData($http,$rootScope,$routeParams,$q) { //$q = promise var deffered = $q.defer(); var data = []; var abbdata = {}; abbdata.async = function () {

我有一个从后端获取数据的工厂:

as.factory("abbdata", function GetAbbData($http,$rootScope,$routeParams,$q) {   //$q = promise
            var deffered = $q.defer();
            var data = [];
            var abbdata = {};

            abbdata.async = function () {
                $http.get($rootScope.appUrl + '/nao/summary/' + $routeParams['id']).success(function(d) {
                data = d.abbData;
                deffered.resolve();
            });

            return deffered.promise;
        };

        abbdata.data = function() {
            return data;
        };

        return abbdata;
        });
在我的控制器中这样呼叫我的工厂:

abbdata.async().then(function() {
        $scope.abbData = abbdata.data(); //Contains data
    });
当我在服务调用之外执行
console.log($scope.abbData)
时,就在下面,结果是不精确的。为什么?调用后,
$scope.abbData
是否应该包含来自我的服务的数据

编辑:


您需要将应返回的数据传递到解析函数中,如下所示:

deffered.resolve(data);
编辑: 要获取控制器中的数据,请执行以下操作:

abbdata.async().then(function(data) {
        $scope.abbData = data; //Contains data
    });

为什么不首先从异步调用返回该值呢

通过在工厂中附加一个成功处理程序并从中返回一个值,您可以将代码简化为:

as.factory("abbdata", function GetAbbData($http,$rootScope,$routeParams) {
    return {
        async: function () {
            return $http.get($rootScope.appUrl + '/nao/summary/' + $routeParams['id']).success(function(d) {
                return d.data.abbData;
            });
        }
     }
});
然后像这样使用它

abbdata.async().then(function(data) {
    $scope.abbData = data; //Contains data
});
如果您
console.log($scope.abbData)
在服务调用之外,它应该显示
undefined
,因为调用是异步的

abbdata.async().then(function() {
    $scope.abbData = abbdata.data(); //Contains data
});
console.log($scope.abbData) // this should show undefined
设置abbData之后,console.log($scope.abbData)应该显示数据

abbdata.async().then(function() {
    $scope.abbData = abbdata.data(); //Contains data
    console.log($scope.abbData) // this should show the data
});
编辑

您可以使用来自服务调用的数据,例如

angular.module('myApp', []).controller('HomeCtrl', function($scope, abbdata){
    var updateUI;    
    $scope.abbData = [];

    abbdata.async().then(function() {
        $scope.abbData = abbdata.data(); //Contains data
        updateUI();
    });
    updateUI = function(){
        //do something with $scope.abbData
    }
});
编辑2

在回答你的问题时,我会这样做

angular.module('myApp', [])
.controller('JobsCtrl', function($scope, $jobService) {
    $scope.jobs = [];
    $jobService.all().then(function(jobs) {
        $scope.jobs = jobs;
    });
})
.service('$jobService', function ($q, $http) {
    return {
        all: function () {
            var deferred = $q.defer();
            $http({
                url: 'http://url',
                method: "GET"
            }).success(function (data) {
                deferred.resolve(data);
            }).error(function () {
                deferred.reject("connection issue");
            });
            return deferred.promise;
        }
    }    
});
关联视图

<body ng-app = "myApp">
    <div ng-controller = "JobsCtrl">
        <div ng-repeat="job in jobs track by job.id">
            <a href="#/tab/jobs/{{job.id}}" class="item item-icon-right">
                <h2>{{job.job_name}}</h2>
                <p>DUE DATE: {{job.job_due_date}}</p>
            </a>
        </div>
    <div>
</body>

  • 这里的服务是一个all函数,它返回一个承诺,即它将在获取数据时发出通知
  • 在控制器中,服务被调用,一旦服务调用被解析,$scope.jobs由解析的数据分配
  • $scope.jobs用于角度视图。一旦解析作业数据,即分配了$scope.jobs,视图就会更新

  • 希望这有帮助

    我快速浏览了一下,我有两个想法:

    • 第一个理论:您的服务返回未定义
    • 第二个理论:您需要运行$scope。$apply()
    看这个小提琴手:

    为了我自己的方便,我去掉了很多依赖项,用q替换了$q

    在上面的示例中,我首先尝试使用伪数据运行代码,控制台输出预期的数据,然后尝试不分配数据,得到一个空数组。这就是为什么我假设如果您看到“undefined”,那么必须显式地将值设置为“undefined”

    除此之外,我还注意到您通过直接从$scope读取来测试结果。我知道,当不在角度范围内时,对$scope对象执行操作不一定会及时发生,键入$scope.$apply()通常可以解决这一问题。通常,在使用$http时,angular会将您保持在适当的范围内,但您正在使用$q创建自己的承诺,因此这可能是另一个潜在问题

    最后,其他两个答案指出,您没有以标准方式使用承诺。尽管您的代码工作正常,但将数据直接设置到服务上并从中检索数据是不正常的。您可以通过简单地用您希望在then方法中处理的数据来解决您的承诺,从而保持您的服务无状态,如Anzeo和Markus的回答所示

    我希望我能找到解决办法,祝你好运


    Dipun

    它仍然未定义。您是否可以使用调试器检查是否在您的服务工厂中调用了success函数?如果这里定义了“d”?嗯,我不知道。但是为什么我的代码不起作用呢?我做错了什么?我想说:)Markus解释说,这是因为您没有将数据传递给resolve调用。我已经将此添加到我的回答中。我尝试了Markus代码示例,但仍然得到一个错误$scope.abbData未定义。我在您的代码样本中得到了相同的错误。您确定调用返回数据吗?:)记录结果变量
    d
    ,查看结果是什么gives@Markus,不,它仍然返回一个承诺。Success只是
    then(function(){})
    的简写,而
    catch
    then(undefined,function(){})
    的简写。我怎样才能使我的服务调用中的数据在我的服务调用之外可以访问?你必须以基于承诺的方式设计你的应用程序。另一方面,如果您使用像
    ng repeat
    这样的角度指令,它将自动更新您的UI,因为
    $scope
    对象监视数据的更改是否有其他方法可以在调用我的服务之外访问我的服务中的数据?你应该怎么做?@shaikb:我必须始终将要使用$scope.abbData的代码放在我的服务调用中吗?不一定,请参阅我的第一次编辑。您可以编写一个函数,例如使用
    $scope.abbData
    并在服务返回数据后调用该函数。但取决于
    $scope.abbData
    的是功能必须在服务返回数据后启动,即解析
    'use strict';
    var GetAbbData = function($q) {   
    //$q = promise
    var deffered = $q.defer();
    var data = [];
    var abbdata = {};
    
    abbdata.async = function () {
        setTimeout(function() {
            //1: set dummy data
            //data = [200, 201];
            //2: do nothing
            //
            //3: set data as undefined
            //data = undefined;
            deffered.resolve();
        }, 100);
    
        return deffered.promise;
    };
    
    abbdata.data = function() {
        return data;
    };
    
    return abbdata;
    };
    var abbdata = GetAbbData(Q)
    abbdata.async().then(function() {
        console.log(abbdata.data()); //Contains data
    });
    
    as.factory("abbdata", function GetAbbData($http,$rootScope,$routeParams,$q) {   //$q = promise
                var deffered = $q.defer();
                var data = [];
                var abbdata = {};
    
                abbdata.async = function () {
                    $http.get($rootScope.appUrl + '/nao/summary/' + $routeParams['id']).success(function(d) {
                    data = d.abbData;
                    deffered.resolve(data);
                });
    
                return deffered.promise;
            };
    
            abbdata.data = function() {
                return data;
            };
    
            return abbdata;
            });