Цепочка AngularJS обещает в контроллере. Этот обходной путь действителен?

0

Примечание: это в TypeScript/Angular 1.4.x

Plunker в javascript: http://plnkr.co/edit/LCka4CFLcRe0lPEF9AM2?p=preview

Мне нужно объединить несколько вызовов с обещаниями. init3 зависит от init2 зависит от init1.

Некоторые из обещаний необходимо продолжить, даже если они потерпят неудачу. Поэтому мне пришлось использовать сплющенную технику здесь: http://solutionoptimist.com/2013/12/27/javascript-promise-chains-2/ Для повторного использования кода обратного вызова.

Проблема в том, что когда цепочка обещает, я полностью теряю контроллер this экземпляра внутри 1-й цепи (init2 и init3). Поэтому я изменил внутренний возврат, чтобы передать контроллер в цепочке, чтобы привязки (привязка к контроллеру) и сервисы были доступны.

Действительно ли это/правильно? (передача контроллера в цепочку и повторное использование обратного вызова для успеха/ошибки)

Комментарии в коде также объясняют/задают вопросы.

Код:

export class ControllerX {

    private myInformation: string;
    private myMoreInformation: string;

    public constructor(private $q: ng.IQService, private service1: Service1) {

        this.init()
            .then(this.init2) //If init() fails dont continue the chain
            .then(this.init3, this.init3); //Even if init2() fail, we continue.
            //init2() cannot fail now but its a recovery example.
    }

    private init(): ng.IPromise<ControllerX> {
        return this.service1.getMyInformation().then((information: string): ControllerX => {
            this.myInformation = information;
            return this; //Push this for the next then
        }); //Do nothing on error, let it propagate.
    }

    private init2(ctrl?: ControllerX): ng.IPromise<ControllerX> {

        if (!ctrl) { //Are we called from a chain
            ctrl = this;
        }

        return ctrl.service1.getMyMoreInfo().then((information: string): ControllerX => {
            ctrl.myMoreInformation = information;
            return ctrl;
        }, (error: any): ControleurListeCours => {
            ctrl.myMoreInformation = DEFAULT;
            return ctrl;
        });
    }

    private init3(ctrl?: ControllerX): ng.IPromise<ControllerX> {
        //blablabla
    }
}
  • 0
    Мой случай другой. Первый вызов init () на самом деле является эквивалентом жирной стрелки. Это прекрасно работает там. Я теряю это во втором. (Связанный, init2 и init3) Вот почему я должен начать возвращать контроллер в связанных обещаниях в качестве параметров.
  • 0
    я возвращаю "this", чтобы init2 мог получить контроллер в качестве параметра. (цепочка обещаний) я не нашел другого способа доступа к контроллеру внутри init2.
Теги:
promise
controller
chaining

1 ответ

0

Этот код не будет работать должным образом.

 this.init()
        .then(this.init2) //If init() fails dont continue the chain
        .then(this.init3, this.init3); //Even if init2() fail, we continue.
        //init2() cannot fail now but its a recovery example.

Если init завершается с ошибкой, код пропускает init2 но будет пойман вторым методом then, и init3 будет выполнен.

HTML

<div ng-app="myApp" ng-controller="myVm as vm">
  <pre>
init1 status = {{vm.init1Status}}
init2 status = {{vm.init2Status}}
init3 status = {{vm.init3Status}}
  </pre>
</div>

JS

angular.module('myApp',[]).controller('myVm', function ($q) {
    var vm = this;
    vm.init1Status = "not done";
    vm.init2Status = "not done";
    vm.init3Status = "not done";

    function init1() {
      vm.init1Status = "init1 failed";
      return $q.reject("init1 failed");
    };

    function init2() {
      vm.init2Status = "init2 done";
    };

    function init3() {
      vm.init3Status = "init3 done";
    };

    init1().then(init2).then(init3,init3);
});

Результат

init1 status = init1 failed
init2 status = not done
init3 status = init3 done

JSFiddle

  • 0
    @georgeawd Привет, спасибо за ответ. Я сделал несколько тестов и увидел эту проблему. Поэтому я изменил свой случай, поэтому, когда я хочу остановить цепочку, я возвращаю отклонение. теперь это выглядит примерно так, но первоначальная идея остается в силе и работает: init1().then(init2, stop).then(init3,stop).then(stop); function stop(ctrl) { ctrl.loading=false; $q.reject(); }
  • 0
    @georgeawd Я также вижу, что в чистом JS у меня нет проблемы, которая есть у меня в TypeScript. Моя версия на plunker - это JavaScript, сгенерированный из компиляции TypeScript. Если вы выполните отладку, вы увидите, что внутри init2 контекст теряется. Модифицированный Fiddle для лучшего управления цепочкой. : ссылка
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню