Должен ли я и как переходить 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");
        });
    }   
  }
});
Другие вопросы по тегам