如何避免回调地狱

kol*_*rie 5 javascript callback angularjs

我在AngularJS中有这个确认需要两个回调:一个是用户点击是,另一个是用户点击对话框上的否.

我需要先询问用户是否完成了操作,如果他回答是,我还需要询问是否要将用户添加为管理员.无论对这两个问题的回答如何,我都需要保留数据.

所以我有这个可怕的,回调地狱出没的代码来处理我上面提到的分支:

$scope.promptAndSave = function() {

  // first question
  $scope.confirmation.display("Confirmation", "Did you finish working on this Reference Check?", function() {

    // handles Yes for first question
    $scope.referenceCheck.finished = true;
    var manager_name = $scope.referenceCheck.first_name + " " + $scope.referenceCheck.last_name;
    $scope.confirmation.display("Add new Manager", "Do you want to add <b>" + manager_name + "</b> as a new manager to your database?", function() {

      // handles Yes for second question
      $scope.referenceCheck.add_manager = true;
      $scope.saveReferenceCheck();

    }, function() {

      // handles No for second question
      $scope.saveReferenceCheck();

    });
  }, function() {

    // handles No for first question
    $scope.saveReferenceCheck();

  });
};
Run Code Online (Sandbox Code Playgroud)

这是否可以通过承诺解决?还是会有更适合这种情况的其他更通用的JS技术?

我理解AngularJS提供$ q,这会有帮助吗?转换为promises时,上面的代码如何显示?

编辑

因此确认是我的本地对象$scope,如下所示:

$scope.confirmation = {
  visible: false,
  title: "",
  prompt: "",
  yes: function() {
    this.visible = false;
    this.yesHandler();
  },
  no: function() {
    this.visible = false;
    this.noHandler();
  },
  display: function(title, prompt, yesHandler, noHandler) {
    this.title = title;
    this.prompt = prompt;
    this.yesHandler = yesHandler;
    this.noHandler = noHandler;
    this.visible = true;
  }
};
Run Code Online (Sandbox Code Playgroud)

我有模板HTML代码,与对象交互以显示提示:

<div id="confirmationForm" ng-show="confirmation.visible">
  <div class="form-title">{{ confirmation.title }}</div>
  <div class="form-body">
    <div class="message" ng-bind-html-unsafe="confirmation.prompt"></div>

    <div class="actions">
      <span>
        <button ng-click="confirmation.yes()">Yes</button>
        <button ng-click="confirmation.no()">No</button>
      </span>
      <img src="/assets/spinner.gif" ng-show="confirmation.busy">
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

编辑2

在一些帮助下,我设法把它放在一起:http://jsfiddle.net/LJr5z/1/

编辑3

要完成,$ q不支持finallyAngular 1.0.3,所以这里是最后一个版本的JSFiddle,使用AngularJS 1.2 - http://jsfiddle.net/LJr5z/3/

Dan*_*ite 5

所以注入$q并试试这个.

$scope.confirmation = {
  visible: false,
  title: "",
  prompt: "",
  yes: function() {
    this.visible = false;
    this.dfd.resolve();
  },
  no: function() {
    this.visible = false;
    this.dfd.reject();
  },
  display: function(title, prompt) {
    this.dfd = $q.defer();
    this.title = title;
    this.prompt = prompt;
    this.visible = true;
    return this.dfd.promise;
  }
};
Run Code Online (Sandbox Code Playgroud)

打电话给它:

$scope.confirmation.display('title', 'prompt')
.then(function() { 
    // return another promise here, yes clicked
}, function() {
    // no clicked
})
.then(...);
Run Code Online (Sandbox Code Playgroud)