1

In an Ember controller, I want to call my API to create a user and on success, transitionToRoute. This is what I currently want to work:

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")
}

But when I place a debugger in the method, this is no longer the controller object and is out of scope to call transitionToRoute.

I've only ever written hacky javascript, but I'm trying to learn core concepts and some frameworks. Is this the right way to use a promise? And is this the right place in Ember to put a transition?

4

2 回答 2

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);
  }

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

于 2015-05-12T03:05:35.843 回答
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");
        });
    }   
  }
});
于 2016-05-30T19:39:09.397 回答