Бился головой о стену, пытаясь понять, как 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.info(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 из обещания отказывается обновлять представление, пока вы не попытаетесь снова вызвать метод.


Как известно, angular.js (или, скорее, печально) использует цикл дайджеста для обнаружения изменений. Встроенные директивы angular, такие как ng-click, будут вызывать $scope.$digest() за вас, но здесь ваше изменение выполняется асинхронно, когда обещание выполняется, и никто не вызывает $digest().
Итак, вы можете либо вызвать $scope.$digest() самостоятельно в блоке then обещания, либо использовать $ q, который является реализацией обещаний angular, где он вызывает $digest за вас.
В Angular есть собственная реализация Promise - $ q. ES6 Promise не запускает цикл дайджеста Angular, вместо этого вы должны использовать $ q.
Если вы настаиваете на использовании ES6 Promise, вы можете вызвать $ 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;
}