【问题标题】:Angular JS success callbackAngular JS 成功回调
【发布时间】:2015-05-20 23:53:51
【问题描述】:

我正在与您联系以获得有关 AngularJS 的 $promise 问题的帮助。

这里是关于 $resource 的文档信息,它也适用于 $http

link

话虽如此,我正在尝试进行 API 调用,并在成功时想要执行回调操作。由于操作是异步进行的,因此甚至在 API 调用完成之前就会发生回调操作。这会导致不正确的数据反射。这是使用 $resource 和 $http 的简单 get 示例。在这两种情况下,实际期望是控制台日志应该显示实际数据,但它会显示承诺数据并导致回调函数甚至在 API 调用完成之前就被调用

$http.get('../../../Employee/GetEmployees').success(function (data) {
        console.log(data);
    });


   return $resource('../../../Employee/GetEmployees', {},
        {
            query: { method: 'GET', isArray: true },
        });

我提供的示例只是为了提供清晰的图片,但我的实际问题来自“PUT”(更新)。按照逻辑,更新必须首先通过 API 调用进行,然后页面需要重定向到 List 页面,在该页面将查询和呈现更新的数据。对此的任何建议将不胜感激。

 $scope.UpdateEmp = function () {
        var empl = $scope.Employee;
        empFactory.empUpdate.update({ EmpID: $routeParams.EmpID, empval: empl }).$promise.then(function () { // update method in my resource uses $resource
            $location.path('/EmpList'); //redirect to list
        });

P.S: 暂时请留下URL,请将其可视化为返回JSON对象的API。

这是完整的代码

这是完整的代码。

路由:

var myApp = angular.module('myApp', ['emp', 'ngRoute']);

myApp.config(function ($routeProvider) {

    $routeProvider
        .when('/',
        {
            templateUrl: 'pages/EmpList.html',
            controller: 'empController'
        }
        )
    .when('/EmpDetail/:EmpID',
    {
        templateUrl: 'pages/EmpDetail.html',
        controller: 'empDetailController'
    }
)
     .when('/EmpList',
    {
        templateUrl: 'pages/EmpList.html',
        controller: 'empController'
    }
    )
     .when('/EmpCreate',
    {
        templateUrl: 'pages/EmpCreate.html',
        controller: 'empCreateController'
    });

});

这里是控制器方法

    myApp.controller('empController', function ($scope, $routeParams, $location, empFactories, empFactory, $http, empHttpFactory) {

            $scope.Employees = empFactories.query();

            $scope.edit = function (EmpID) {
            $location.path('/EmpDetail/' + EmpID);
        };


        $scope.Delete = function (empID) {
            empFactory.empDelete.del({ EmpID: empID }, function () {
                $location.path('/EmpList');
            });
        }

        $scope.Createnew = function () {
            $location.path('/EmpCreate');
        }


    });

    myApp.controller('empDetailController', function ($scope, empFactory,empFactories, $routeParams, $location) {

        $scope.Employee = empFactory.employee.show({ EmpID: $routeParams.EmpID });

        console.log($scope.Employee);

        $scope.UpdateEmp = function () {
            var empl = $scope.Employee;
            empFactory.empUpdate.update({ EmpID: $routeParams.EmpID, empval: empl }).$promise.then(function () { // update method in my resource uses $resource
                $location.path('/EmpList'); //redirect to list
            }); 

        };

    });

Here is the service

var myservice = angular.module('emp', ['ngResource', 'ngRoute']);
myservice.factory('empFactories', function ($resource) {
    return $resource('../../../Employee/GetEmployees', {},
        {
            query: { method: 'GET', isArray: true },
            create: { method: 'POST' }
        });
});

myservice.factory('empFactory', function ($resource) {



    //return $resource('../../Employee/GetEmployee/:EmpID', { EmpID: '@EmpID' },
    //      {
    //          show: { method: 'GET' }
    //      });


    var resource = {
        employee:
            $resource('../../Employee/GetEmployee/:EmpID', { EmpID: '@EmpID' },
           {
               show: { method: 'GET' }

           }),
        empUpdate:
            $resource('../../Employee/PutEmployee/:EmpID', { EmpID: '@EmpID', empval: '@empl' }, { update: { method: 'PUT', isArray: true } }),
        empDelete:
            $resource('../../Employee/DeleteEmployee/:EmpID', { EmpID: '@EmpID' }, { del: { method: 'DELETE', isArray: true } }),

        empCreate:
            $resource('../../Employee/CreateEmployee', { empval: '@empl' }, { create: { method: 'POST', isArray: true } })
    }

    return resource;
});

【问题讨论】:

  • 您能否发布完整代码或检查来自开发人员工具的请求和响应?我发现在收到响应之前成功运行很奇怪。
  • 对于 get 方法,我正在检查开发人员工具控制台日志。对于 Put 方法,正如我所说,期望是“重定向应该在更新后进行”。我对 Put 使用了类似的 onsuccess 条件,正如您在我的示例中看到的那样
  • 我知道您正在努力使问题保持​​简洁,但我无法理解 $http 调用与 return $resource() 的关系 - 这些只是您 API 中的替代方案吗?以及两者与UpdateEmp 函数中的调用有何关系
  • 我在下面的答案部分发布了完整的代码。例如,我比较了 $http 和 $resource。我只使用 $resource 。只是为了确保我不应该将 cmets 作为 ,在 $http 中不会出现此问题,我分享了示例。

标签: angularjs angularjs-resource


【解决方案1】:

首先我看到一个设计问题,你的工厂不应该返回资源,应该返回承诺,

myservice.factory('empFactory', function ($resource) {

  var employeeResource  = $resource('../../Employee/GetEmployee/:EmpID', { EmpID: '@EmpID'}, {show: { method: 'GET' } }),
  updateResource = $resource('../../Employee/PutEmployee/:EmpID', { EmpID: '@EmpID', empval: '@empl' }, { update: { method: 'PUT', isArray: true } }),
  deleteResource = $resource('../../Employee/DeleteEmployee/:EmpID', { EmpID: '@EmpID' }, { del: { method: 'DELETE', isArray: true } }),
  createResource = $resource('../../Employee/CreateEmployee', { empval: '@empl' }, { create: { method: 'POST', isArray: true } });

  return { 
    getEmployee: function(id){
      return employeeResource.get({EmpID: id}).$promise;
    },
    updateEmployee: function(){
      return updateResource.update(...).$promise;
    }
  };
});

我认为问题在于你在打电话

$scope.Employee = empFactory.employee.show({ EmpID: $routeParams.EmpID });

这会立即返回一个资源,因此从技术上讲,您不会在任何地方获得该员工。不是很清楚错误在哪里,您是否尝试并行执行多个资源请求?如果是这样,请使用$q.all([asyncCall1,asyncCall2,...]).spread(function(r1, r2, ...) {...});

问候

【讨论】:

  • 问题在于我的更新语句,$scope.UpdateEmp = function () { var empl = $scope.Employee; empFactory.empUpdate.update({ EmpID: $routeParams.EmpID, empval: empl }).$promise.then(function () { // 我的资源中的更新方法使用 $resource $location.path('/EmpList'); //重定向到列表 });甚至在此之前,我得到了响应,重定向发生了
  • 你怎么知道“还没有响应”?您没有获取$promise.then(function(response){...//redirect}) 中的参数您没有使用响应,还是在其他地方捕获结果?
  • 好的.. 我正在更新调用中对我的模型进行更新。当重定向发生时,我的期望是它查询更新的模型并返回它。一旦页面被重定向,我的模型集合被查询并填充列表页面。
  • 我认为你有几个问题,empController 从不请求员工名单。如果您从 empDetailController 更新您的模型,则与在 empController 上更新模型不同。我建议您使用ui-router 而不是$location.path('/') 使用$state.go('empList',{//data}) 并且在您的empController 中您可以使用$stateParams 来获取发送状态更改的数据,或者在您定义您的状态时甚至更好,您可以添加一个@ 987654329@ 字段,可以包含在状态更改之前已解决的承诺
  • 您正确地解决了问题,您的解决方案听起来也更合乎逻辑。你能不能给我一个工作样本,以便我测试它。抱歉,我是这个角度部分的新手。
【解决方案2】:

您可以使用 $resource 定义 API 路由和 API 处理请求所需的参数。然后,稍后您需要向 $resource 提供数据并执行操作(获取、保存、查询、删除、删除)。

我个人更喜欢使用 $http,因为它非常简洁。缺点是你不能在你的应用中预先定义路由和参数。

这是一个显示 $resource 和 $http 请求的笔。

http://codepen.io/kenhowardpdx/pen/BNzXeE

angular.module('app', ['ngResource']);

MyService.$inject = ['$http', '$resource'];
function MyService ($http, $resource) {
    var _this = this;

    var Search = $resource('http://www.omdbapi.com/?tomatoes=true&plot=full&t=:searchTerm', {searchTerm:'@searchTerm'});

    _this.httpSearch = function (searchTerm) {
        return $http.get('http://www.omdbapi.com/?tomatoes=true&plot=full&t=' + searchTerm);
    };

    _this.resourceSearch = function (searchTerm) {
        return Search.get({searchTerm: searchTerm}).$promise;
    }
}

angular.module('app').service('MyService', MyService);

MyController.$inject = ['MyService'];
function MyController (MyService) {
    var _this = this;

    _this.type = 'http';

    _this.searchFilms = function () {
        if (_this.type === 'http') {
            MyService.httpSearch(_this.searchTerm).then(function(_response) {
               _this.results = _response.data; 
            });
        } else {
            MyService.resourceSearch(_this.searchTerm).then(function(_response) {
               _this.results = _response; 
            });
        }
    }
}

angular.module('app').controller('MyController', MyController);`

【讨论】:

    【解决方案3】:

    工厂不需要返回承诺。我的意思是这取决于你如何管理你的工厂和控制器以及你将如何解决它。

    您的工厂不会返回承诺而是资源,因此它应该在您的控制器中解决。您在控制器中的更新方法应该是这样的:

        $scope.UpdateEmp = function () {
        var empl = $scope.Employee;
        empFactory.empUpdate.update({ EmpID: $routeParams.EmpID, empval: empl }, function (successResponse) { // update method in my resource uses $resource
            $location.path('/EmpList'); //redirect to list
        },function (error) { 
         // do something on error callback
        });
    

    阅读 angularjs 资源angularjs docs about $resource

    【讨论】:

    • 谢谢@konammagari。这里的问题是,它没有调用我的 API 控制器来获取更新的员工列表。仅第一次调用以获取数据,并且从下一次调用我的 API 控制器开始,控件不会获取更新的列表
    • 请在下一个答案部分查看 Matho 的回复。我正在经历与他所定义的完全相同的问题。此外,如果您分享您的电子邮件 ID/电话号码,很高兴与您联系以进行角度查询
    猜你喜欢
    • 2015-01-10
    • 2016-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    相关资源
    最近更新 更多