异步 ng-click/change/submit 事件处理程序

Asynchronous ng-click/change/submit Event Handlers

我有以下代码:

在 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 控制器中的东西吗?例如,returncodeService.deleteFile(file)?

  2. 之前
  3. 我应该 return 在 codeServicefunction (res) { ... } 里面的东西吗?

  4. 当一个 html 模板包含多个具有异步元素的 ng-clickng-changeng-submit 时,每个 ng- 是否阻塞?如果不是,如果我们click/change/submit非常快,那会很乱,不是吗?

以下是构建代码的方法

HTML

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

控制器

$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. 如果不需要,您不必 return 控制器函数中的某些内容。
  2. then 的成功函数中,您实际上可以删除该行。然后如果你有错误,该行不会被删除,你可以显示错误信息
  3. 如果你的异步调用需要时间并且你可以点击多次,它可能会很混乱。该呼叫将进行多次,您将尝试多次删除相同的项目。一种解决方案是在单击按钮时禁用该按钮($scope.deleteFile 内的第一行)或在某处添加加载。您需要阻止用户点击 2 次

Angular 事件处理程序是单线程的,但对于异步操作是非阻塞的。如果 click/change/submit 事件发生得非常快,那会很混乱,是的。值得考虑禁用输入元素,直到异步操作完成或被拒绝。考虑使用 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 时,输入被禁用并出现 Processing 消息。

DEMO on PLNKR


带有 ngModelController 的异步验证器

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

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


do you have any comment about my questions 1 & 2?

函数式编程的经验法则是总是return something

在承诺的情况下,如果拒绝处理程序同时省略了 return 和 throw 语句,链式承诺将从拒绝转换 为已履行的承诺其解析值为 undefined。错误的常见原因,尤其是在 http 拦截器中。

return 嵌套承诺失败将导致父承诺在嵌套承诺完成之前解决。错误的另一个常见原因。

return .then 方法中函数的值失败导致新的派生承诺解析为 undefined。错误的另一个常见原因。

另一方面,一些手指比较纤细的人认为只需要打六个字母就可以了
r e t u r n 仅在绝对必要时才使用。