AngularJS Controller As: Обещание не обновлять представление - PullRequest
0 голосов
/ 29 сентября 2018

Я бился головой о стену, пытаясь понять, как controller as и Promises работают вместе с AngularJS.Похоже, что, завернув результат в обещание, AngularJS не увидит обновления контроллера, пока вы не запустите другое изменение.

HTML:

<body ng-app="MainModule" ng-controller="MainController as main">
    <div class="bar bar-header bar-calm">
        <h1 class="title">Test Bench</h1>
    </div>

    <div class="app">
        <h1>Test Bench</h1>

        <div class="text-center">
            <p>Last Fingerprint Result: {{main.lastAuthSuccessful}}</p>
        </div>
.....
</body>

Рассматриваемый метод контроллера:

doFingerprint() {
    this.auth
      .fingerprint()

      .then(success => {
        console.log(this, self, this.self);
        this.lastAuthSuccessful = success;
      })

      .catch(error => {
        console.error(error);
        return false;
      });
  }

И метод идентификации в сервисе аутентификации:

fingerprint(): Promise<boolean> {
    if (!this.finger) return Promise.reject("Fingerprint API not yet loaded.");

    return new Promise((resolve, reject) => {
      this.finger.show(
        {
          clientId: "Fingerprint-Demo",
          clientSecret: "password"
        },

        () => {
          resolve(true);
        },

        err => {
          resolve(false);
        }
      );
    });
  }

Это выглядит довольно просто, но обновленное lastAuthSuccessful из обещания отказывается обновлять представление, пока вы не попытаетесь вызватьметод снова.

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Angular имеет собственную реализацию Promise, которая составляет $ q .Обещание ES6 не запускает цикл дайджеста Angular, вместо этого вы должны использовать $ q .

Если вы настаиваете на использовании обещания ES6, вы можете вызвать $ scope. $ Apply ().$ apply () используется для выполнения выражения в AngularJS извне платформы AngularJS.(Например, из событий DOM браузера, setTimeout, XHR или сторонних библиотек).

Обычно вы не не вызываете $ digest () непосредственно в контроллерах или в директивах.Вместо этого вы должны вызвать $ apply () (обычно из директивы), что вызовет $ digest ().

fingerprint(): Promise<boolean> {
    let deferred = $q.defer();
    if (!this.finger) return $q.reject("Fingerprint API not yet loaded.");

    this.finger.show(
        {
          clientId: "Fingerprint-Demo",
          clientSecret: "password"
        },

        () => {
          deferred.resolve(true);
        },

        err => {
          deferred.resolve(false);
        }
      );

    return deferred.promise;
}
0 голосов
/ 29 сентября 2018

angular.js классно (или довольно печально) использует цикл дайджеста для обнаружения изменений.Встроенные угловые директивы, такие как ng-click, будут вызывать $scope.$digest() для вас, но здесь ваше изменение выполняется асинхронно, когда обещание разрешается, и никто не вызывает $digest().

Итак, вы можете либо позвонить $scope.$digest() сами в блоке then обещания, или вы можете использовать $ q , который является реализацией обещаний angular, где он вызывает для вас $digest.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...