如何重构Angular对回调的承诺

How to refactor Angular promise to Callback?

本文关键字:回调 承诺 Angular 何重构 重构      更新时间:2023-09-26

我有一个控制器初始化方法,它初始化模板中的自动完成输入:

$scope.initAutoCompleteForWorkers = function (id) {
        // INIT AUTOCOMPLETE FOR WORKERS
        var promise = GlobalHelperService.workersListForAutocomplete();
        promise.then(
            function(answer) {
                // do something
                console.log("Answer");
                console.log(answer);
                console.log("Name" + answer.name);
                console.log("Surname" + answer.surname);
                //$scope.projectDetail.newWorker = "";
                //$scope.projectDetail.newWorkerName = "";
                $scope.projectDetail.newWorker = answer;
                $scope.projectDetail.newWorkerName = answer.name +" "+answer.surname ;
            },
            function(error) {
                // report something
                console.log("Error");
                console.log("Processing error with status " +status);
                growlNotifications.add($translate.instant('PROCESSING_REQUEST_ERROR') + jsonResponse.message , 'error',  $rootScope.notificationLifetime);
            },
            function(progress) {
                // report progress
                console.log("Progres");
            });
    };

这是init方法,应该在每个select事件之后返回deffered.resolve。

this.workersListForAutocomplete =  function (container, options) {
         var deferred = $q.defer();
         $("#autocompleteWorker").kendoAutoComplete({
             dataSource :  {
                 type: "json",
                 serverFiltering: true,
                 transport: {
                     read: function (options) {
                         console.log("List");
                         console.log(options.data);
                         requestParams = {
                             "entityName": "worker",
                             "page": 1,
                             "pageSize": 20,
                             "filter": options.data.filter,
                             "sort": [
                                 {
                                     "field": "name",
                                     "ord": "asc"
                                 }
                             ]
                         };
                         ApiService.doHttpRequest(
                             "POST",
                             $rootScope.apiBaseUrl + "worker/search",
                             requestParams
                         )
                         .success(function (data, status, headers, config) {
                             // successful data retrieval
                             console.log("request success, checking state");
                             console.log(data);
                             // sent status to global HTTP status service
                             var jsonResponse =  ApiService.processReturnedHttpState(status);
                             console.log("Status response is " + jsonResponse.result);
                             // do something with data
                             switch (jsonResponse.result) {
                                 case true:
                                     options.success(data.results);
                                     break;
                                 case false:
                                     growlNotifications.add($translate.instant('LIST_LOADING_ERROR'), 'error',  $rootScope.notificationLifetime);
                                     break;
                             }
                         })
                         .error(function (data, status, headers, config) {
                             deferred.reject(e);
                             // hide loading spinner
                             kendo.ui.progress(gridView, false);
                         });
                     }
                 }
             },
             //dataTextField: "name",
             dataValueField: "id",
             template: '#: data.name # #: data.surname #',
             filter: "contains",
             minLength: 1,
             select  : function (e) {
                 console.log("select");
                 var dataItem = this.dataItem(e.item.index());
                 console.log(dataItem);
                 deferred.resolve(dataItem);
             }
         });
         return deferred.promise;
     };

问题是function(answer) {仅在第一次选择事件时被调用。第二次和更多的是不应答promise事件调用(并且输入由[Object,Object]值填充)。

我发现更好的解决方案应该是使用回调或事件,但我不知道如何以正确的方式进行。

有人能告诉我,怎么做对吗?

谢谢你的帮助。

您可以通过以下方式使用回调:

this.workersListForAutocomplete =  function (container, options,callback) {
     $("#autocompleteWorker").kendoAutoComplete({
         dataSource :  {
             type: "json",
             serverFiltering: true,
             transport: {
                 read: function (options) {
                     console.log("List");
                     console.log(options.data);
                     requestParams = {
                         "entityName": "worker",
                         "page": 1,
                         "pageSize": 20,
                         "filter": options.data.filter,
                         "sort": [
                             {
                                 "field": "name",
                                 "ord": "asc"
                             }
                         ]
                     };
                     ApiService.doHttpRequest(
                         "POST",
                         $rootScope.apiBaseUrl + "worker/search",
                         requestParams
                     )
                     .success(function (data, status, headers, config) {
                         // successful data retrieval
                         console.log("request success, checking state");
                         console.log(data);
                         // sent status to global HTTP status service
                         var jsonResponse =  ApiService.processReturnedHttpState(status);
                         console.log("Status response is " + jsonResponse.result);
                         // do something with data
                         switch (jsonResponse.result) {
                             case true:
                                 options.success(data.results);
                                 break;
                             case false:
                                 growlNotifications.add($translate.instant('LIST_LOADING_ERROR'), 'error',  $rootScope.notificationLifetime);
                                 break;
                         }
                     })
                     .error(function (data, status, headers, config) {
                         callback(e,null);
                         // hide loading spinner
                         kendo.ui.progress(gridView, false);
                     });
                 }
             }
         },
         //dataTextField: "name",
         dataValueField: "id",
         template: '#: data.name # #: data.surname #',
         filter: "contains",
         minLength: 1,
         select  : function (e) {
             console.log("select");
             var dataItem = this.dataItem(e.item.index());
             console.log(dataItem);
             callback(null,dataItem);
         }
     });
     return deferred.promise;
 };

并且在您的控制器中:

$scope.initAutoCompleteForWorkers = function (id) {
        // INIT AUTOCOMPLETE FOR WORKERS
    GlobalHelperService.workersListForAutocomplete(function(err,answer){
        if(err){
            // report something
            console.log("Error");
            console.log("Processing error with status " +status);
            growlNotifications.add($translate.instant('PROCESSING_REQUEST_ERROR') + jsonResponse.message , 'error',  $rootScope.notificationLifetime);
        } else {
            // do something
            console.log("Answer");
            console.log(answer);
            console.log("Name" + answer.name);
            console.log("Surname" + answer.surname);
            //$scope.projectDetail.newWorker = "";
            //$scope.projectDetail.newWorkerName = "";
            $scope.projectDetail.newWorker = answer;
            $scope.projectDetail.newWorkerName = answer.name +" "+answer.surname ;
        }
    });
};