Должен ли я и как переходить ToRoute в обещание обратного вызова
В контроллере 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
,
Я только когда-либо писал хакерский javascript, но я пытаюсь изучить основные понятия и некоторые основы. Это правильный способ использовать обещание? И это правильное место в Эмбер, чтобы поставить переход?
2 ответа
Ваша проблема не имеет ничего общего с 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);
}
Теперь этот код начинает выглядеть более семантическим и читабельным.
Альтернативное решение - просто использовать синтаксис стрелки 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");
});
}
}
});