我曾用头撞墙,试图弄清楚controller as
和Promises如何与AngularJS一起工作。通过将结果包装在Promise中,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;
});
}
以及auth服务中的指纹方法:
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
拒绝更新视图,直到您尝试再次调用该方法为止。
答案 0 :(得分:0)
angular.js著名(或臭名昭著)使用the digest loop进行更改检测。像ng-click
这样的内置角度指令会为您调用$scope.$digest()
,但是在您的更改是在诺言解决后异步进行的,没有人调用$digest()
。
因此,您可以在promise的$scope.$digest()
块中自己调用then
,也可以使用$q(它是Promises的angular的实现),它调用{{ 1}}。
答案 1 :(得分:0)
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;
}