如何避免回调地狱

时间:2013-12-27 20:52:29

标签: javascript angularjs callback

我在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();

  });
};

这是否可以使用promises解决?或者其他更通用的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;
  }
};

我有模板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>

编辑2

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

编辑3

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

1 个答案:

答案 0 :(得分: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;
  }
};

要打电话:

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