异步ng-单击/更改/提交事件处理程序

时间:2017-03-02 14:35:54

标签: angularjs asynchronous angular-promise angular-http

我有以下代码:

在html模板中,ng-click链接到函数deleteFile

<div ng-repeat="file in files track by $index">
    <a ng-click="deleteFile(file)">delete</a>
</div>

在控制器中,函数deleteFile调用另一个包含异步元素的函数codeService.deleteFile

$scope.deleteFile = function (file) { 
    var index = $scope.files.indexOf(file);
    if (index > -1) $scope.files.splice(index, 1);

    codeService.deleteFile(file)
};
codeService.deleteFile中的

,它有一个异步调用$httpthen,其中包含同步代码。

this.deleteFile = function (file) {
    return $http.post('/rmFile', { dir: prefix + idP + "/", file: file })
        .then(function (res) {
            console.log("codeService, physical deleteFile, done: " + res.data.name);
            var iframe = document.getElementById('myiframe'); 
            iframe.src = iframe.src
        })
}

人们说when using promise always return,我想知道组织这些异步同步混合代码的最佳做法是什么。确切地说,我有一些问题,例如,

  1. 我应该在控制器中返回一些内容吗?例如return之前的codeService.deleteFile(file)

  2. 我应该在function (res) { ... }的{​​{1}}内返回一些内容吗?

  3. 当html模板包含多个具有异步元素的codeServiceng-clickng-change时,每个ng-submit是否会阻止?如果没有,如果我们非常快地点击/更改/提交,那会很麻烦,不是吗?

2 个答案:

答案 0 :(得分:2)

以下是如何构建代码

<强> HTML

<div ng-repeat="file in files track by $index">
    <a ng-click="deleteFile(file)">delete</a>
</div>

<强> CONTROLLER

$scope.deleteFile = function (file) { 
    var index = $scope.files.indexOf(file);
    if (index > -1) $scope.files.splice(index, 1);

    codeService.deleteFile(file).then(function(response){
        console.log("codeService, physical deleteFile, done: " + res.data.name);
    }, function(err){
        console.log("codeService, physical deleteFile, FAIL: " + res.data.name);
    });
};

<强>服务

this.deleteFile = function (file) {
    return $http.post('/rmFile', { dir: prefix + idP + "/", file: file });
}

<强>答案

  1. 如果不需要,您无需在控制器功能内部返回任何内容。
  2. then的成功功能中,您实际上可以删除该行。然后,如果您有错误,则不会删除该行,并且您可以显示错误消息
  3. 如果您的异步调用需要多次,并且您可以多次单击,则可能会很麻烦。呼叫将多次完成,您将尝试删除相同的项目倍数。解决方案是在单击按钮时禁用按钮($scope.deleteFile内的第一行)或在某处添加加载。您需要阻止用户单击2次

答案 1 :(得分:2)

Angular事件处理程序是单线程的,但对于异步操作是非阻塞的。如果点击/更改/提交事件发生得非常快,那将是混乱的,是的。值得考虑禁用输入元素,直到异步操作完成或已完成或被拒绝。考虑使用ng-disabled directive

<button ng-click="decrease()" ng-disabled="wait">Decrease</button>
<p ng-show="wait" style="color: red">Processing</p>

JS

vm.decrease = function() {
    vm.wait = true;
    return $http.delete("url").then( function(response) {
      vm.quantity--;
      vm.wait = false;
      return response;
    }).catch( function(errorResponse) {
      vm.wait = false;
      throw errorResponse;
    });
};

在上面的示例中,点击处理程序会立即设置wait标记true。然后,当XHR完成或已完成时,它会重置标志。当等待标志为true时,输入被禁用,并出现处理消息。

DEMO on PLNKR

使用ngModelController

的异步验证器

ngModelController设置$pending标志,可用于在进行异步验证时禁用输入。

有关详细信息,请参阅AngularJS ngModelController API Reference - $asyncValidators

  

你对我的问题有任何评论1&amp; 2?

功能编程中的经验法则总是返回

对于promises,如果拒绝处理程序省略了return和throw语句,则链式承诺将转换从拒绝转换为履行的承诺,该承诺以{{1 }}。导致错误的常见原因,特别是在http拦截器中。

未能返回嵌套的promise将导致父承诺在嵌套的promise完成之前解析。错误的另一个常见原因。

未能在undefined方法中向函数返回值会导致新派生的promise转换为.then。另一个常见的错误原因。

另一方面,一些手指细腻的人认为只应输入六个字母 r e t u r n 仅在绝对必要时才使用。