ES6承诺不更新AngularJS DOM

时间:2017-02-09 01:19:46

标签: javascript angularjs angular-promise es6-promise

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



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

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

myModule.component('myComponent', {
  template: `<div>{{$ctrl.data}}</div>`,
  controller: myComponent
});
&#13;
    <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>
&#13;
&#13;
&#13;

它打印得很好......现在,如果我进行一些小修改并使其异步:

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

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

myModule.component('myComponent', {
  template: `<div>{{$ctrl.data}}</div>`,
  controller: myComponent
});
&#13;
<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>
&#13;
&#13;
&#13;

它不会打印任何东西。我可以通过点击处理程序改变价值,但对于http和其他异步操作,它不会起作用。

2 个答案:

答案 0 :(得分:2)

使用$q.when将ES6承诺转换为AngularJS承诺

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

使用$q.when将外部承诺转换为Angular框架承诺:

function myComponent(){
  //Promise.resolve().then(_ => {
  //USE $q.when
  $q.when(Promise.resolve()).then(_ => {
    this.data = 'Hello World';
  });
}

使用$ q与AngularJS框架及其摘要周期正确集成的服务承诺。

  

$ q.when

     

将可能是值的对象或(第三方)随后的承诺包含到$q承诺中。当您处理可能会或可能不是承诺的对象,或者承诺来自不可信任的来源时,这非常有用。

     

-- AngularJS $q Service API Reference - $q.when

答案 1 :(得分:1)

当您运行异步代码时,您需要让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,还添加了函数参数。

Read more about $scope.$apply and $scope.digest