我应该如何在promise回调中转换到转发

时间:2015-05-12 02:58:03

标签: javascript ember.js callback promise ic-ajax

在Ember控制器中,我想调用我的API来创建用户,并在成功时调用transitionToRoute。这就是我目前想要的工作:

import ajax from "ic-ajax";
import Ember from "ember";

export default Ember.Controller.extend({
  actions: {  
    createAndLoginUser: function() {
      var user = { "user": this.getProperties("email", "name") };
      ajax({ url: "api/users", type: "POST", data: user })
        .then(transitionToHome);
    }   
  }
});

var transitionToHome = function() {
  this.transitionToRoute("home")
}

但是当我在方法中放置debugger时,this不再是控制器对象,而且超出了调用transitionToRoute的范围。

我只写过hacky javascript,但我试图学习核心概念和一些框架。这是使用承诺的正确方法吗?这是在Ember进行过渡的正确位置吗?

2 个答案:

答案 0 :(得分:3)

你的问题与Ember或过渡无关;它是关于this处理的全部内容。最简单的解决方案就是

.then(transitionToHome.bind(this));

将转换方法放在控制器

您还可以考虑将transitionToHome作为方法放在控制器中。然后,您可以按以下方式调用它:

export default Ember.Controller.extend({

  transitionToHome: function() { this.transitionToRoute("home"); },

  actions: {  
    createAndLoginUser: function() {
      var self = this;
      var user = { "user": this.getProperties("email", "name") };
      ajax({ url: "api/users", type: "POST", data: user })
        .then(function() { self.transitionToHome(); });
    }   
  }

});

这可能是一种更简单的方法,更易读,不需要推理this并使用bind(但需要使用self)。

将过渡转移到路线?

在你的问题范围之外,但有些人会说路由相关的逻辑(包括转换)逻辑上属于路由,而不是控制器。如果您同意,您可以重构上述内容以执行send

createAndLoginUser: function() {
  var user = { "user": this.getProperties("email", "name") };
  var self = this;
  ajax({ url: "api/users", type: "POST", data: user })
    .then(function() { self.send("goHome"); });
  }
}

然后在您的路线中实施goHome操作。或者,您可以在更高级别的路由中实现goHome,甚至是应用程序路由,从而使其可以从任何控制器或更低级别的路由中使用。

将AJAX逻辑移动到服务?

其他人可能会说ajax逻辑并不真正属于控制器,并且应该正确地位于服务层中,所以

// services/user.js
export function createUser(data) {
  return ajax({ url: "api/users", type: "POST", data: { user: data } });
}

// controller
import { createUser } from 'app/services/user';

export default Ember.Controller.extend({
  createAndLoginUser: function() {
    var data = this.getProperties("email", "name"));
    var self = this;
    createUser(data) . then(function() { self.send("goHome"); });
  }
};

使用ES6语法,我们可以避免self,简化过程中的一点:

  createAndLoginUser: function() {
    var data   = this.getProperties("email", "name"));
    var goHome = () => this.send("goHome");

    createUser(data) . then(goHome);
  }

现在这段代码开始看起来更具语义性和可读性。

答案 1 :(得分:1)

另一种解决方案是简单地使用ES6箭头语法来维护this

的上下文
import ajax from "ic-ajax";
import Ember from "ember";

export default Ember.Controller.extend({
  actions: {  
    createAndLoginUser() {
      let user = { "user": this.getProperties("email", "name") };
      ajax({ url: "api/users", type: "POST", data: user })
        .then(() => {
          this.transitionToRoute("home");
        });
    }   
  }
});