ES6 Promise不更新 AngularJS DOM

IT技术 javascript angularjs angular-promise es6-promise
2021-03-10 13:44:24

我无法理解角度组件的范围。如果我做这样的事情:

function myComponent(){
  this.data = 'Hello World';
}

let myModule = angular.module('myModule', []);

myModule.component('myComponent', {
  template: `<div>{{$ctrl.data}}</div>`,
  controller: myComponent
});
    <script data-require="angularjs@1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="myModule">
  <my-component></my-component>
</div>

它打印得很好......现在,如果我做一个小的修改并使它异步:

function myComponent(){
  Promise.resolve().then(_ => {
    this.data = 'Hello World';
  });
}

let myModule = angular.module('myModule', []);

myModule.component('myComponent', {
  template: `<div>{{$ctrl.data}}</div>`,
  controller: myComponent
});
<script data-require="angularjs@1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="myModule">
  <my-component></my-component>
</div>

它不打印任何东西。我可以使用单击处理程序更改该值,但是对于 http 和其他异步操作,它不起作用。

2个回答

使用$q.when转换器ES6PromiseAngularJSPromise

AngularJS 通过提供自己的事件处理循环来修改正常的 JavaScript 流程。这将 JavaScript 分为经典和 AngularJS 执行上下文。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等...... 1由于 promise 来自 AngularJS 框架之外,因此该框架不知道模型的更改并且不会不更新 DOM。

使用$q.when到外部的Promise转换为AngularJS框架的Promise:

function myComponent(){
  ̶P̶r̶o̶m̶i̶s̶e̶.̶r̶e̶s̶o̶l̶v̶e̶(̶)̶.̶t̶h̶e̶n̶(̶_̶ ̶=̶>̶ ̶{̶
  //USE $q.when
  $q.when(Promise.resolve()).then(_ => {
    this.data = 'Hello World';
  });
}

使用与 AngularJS 框架及其摘要循环正确集成的 $q 服务Promise。

$q.when

将可能是值或(第 3 方) then-able Promise的对象包装到$qPromise中。当您处理可能是也可能不是Promise的对象,或者Promise来自不可信任的来源时,这很有用。

AngularJS $q 服务 API 参考 - $q.when

当您运行异步代码时,您需要让 Angular 知道某些内容已更新。这使得 angular 运行一个 $digest 循环,检查是否有任何绑定需要更新。

为此,请将您的作业包装在对 的调用中$scope.$apply()

function myComponent($scope){
  Promise.resolve().then(_ => {
    $scope.$apply(() => {
      this.data = 'Hello World';
    });  
  });
}

let myModule = angular.module('myModule', []);

myModule.component('myComponent', {
  template: `<div>{{$ctrl.data}}</div>`,
  controller: myComponent
});
<script data-require="angularjs@1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="myModule">
  <my-component></my-component>
</div>

请注意,我$scope不仅在函数体中添加,而且还作为函数参数添加。

阅读更多关于$scope.$apply$scope.digest

为什么我不需要用控制器这样做?我可以简单地做$scope.data = "Hello World"而不需要$scope.apply
2021-05-01 13:44:24
我正在尝试它module.controller,通过绑定到组件(例如<my-component data="data"></my-component>将它传递下来,并且不需要$scope.$apply,尽管如果我隔离控制器它不起作用并且我确实需要它。
2021-05-06 13:44:24
你不能在你提供的例子中。在 Angular 不知道的情况下将属性分配给$scopethis异步,不会触发 $digest。AngularJS 通常会在您使用ng-click$http回调等时为您调用 $apply 函数,但这些是 Angular 内置函数
2021-05-18 13:44:24