如何在 Angular 1.5 组件中等待绑定(没有 $scope.$watch)

How to wait for binding in Angular 1.5 component (without $scope.$watch)

本文关键字:没有 绑定 scope watch 等待 Angular 组件      更新时间:2023-09-26

我正在编写一个 Angular 1.5 指令,在绑定数据存在之前尝试操作绑定数据时遇到了一个令人讨厌的问题。

这是我的代码:

app.component('formSelector', {
  bindings: {
    forms: '='
  },
  controller: function(FormSvc) {
    var ctrl = this
    this.favorites = []
    FormSvc.GetFavorites()
    .then(function(results) {
    ctrl.favorites = results
    for (var i = 0; i < ctrl.favorites.length; i++) {
      for (var j = 0; j < ctrl.forms.length; j++) {
          if (ctrl.favorites[i].id == ctrl.newForms[j].id) ctrl.forms[j].favorite = true
      }
     }
    })
}
...

如您所见,我正在进行 AJAX 调用以获取收藏夹,然后根据我的绑定表单列表对其进行检查。

问题是,甚至在填充绑定之前,承诺就已经实现了......因此,当我运行循环时,ctrl.forms仍未定义!

如果不使用 $scope.$watch(这是 1.5 组件吸引力的一部分),如何等待绑定完成?

我遇到了类似的问题,我这样做是为了避免在我要发送的值准备就绪之前调用组件:

<form-selector ng-if="asyncValue" forms="asyncValue" ></form-selector>

您可以使用新的生命周期挂钩(特别是 $onChanges ),通过调用 isFirstChange 方法来检测绑定的第一次更改。在此处阅读有关此内容的更多信息。

下面是一个示例:

<div ng-app="app" ng-controller="MyCtrl as $ctrl">
  <my-component binding="$ctrl.binding"></my-component>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js"></script>
<script>
  angular
    .module('app', [])
    .controller('MyCtrl', function($timeout) {
      $timeout(() => {
        this.binding = 'first value';
      }, 750);
      $timeout(() => {
        this.binding = 'second value';
      }, 1500);
    })
    .component('myComponent', {
      bindings: {
        binding: '<'
      },
      controller: function() {
        // Use es6 destructuring to extract exactly what we need
        this.$onChanges = function({binding}) {
          if (angular.isDefined(binding)) {
            console.log({
              currentValue: binding.currentValue, 
              isFirstChange: binding.isFirstChange()
            });
          }
        }
      }
    });
</script>

原海报上写着:

甚至在填充绑定之前,承诺就已经实现...... 因此,当我运行循环时,ctrl.forms仍未定义

从 AngularJS 1.5.3 开始,我们就有了生命周期钩子,为了满足 OP 的问题,你只需要移动依赖于$onInit()内满足绑定的代码:

$onInit() - 在 元素已被构造并初始化了其绑定(和 在 pre 和 post 链接功能之前,用于此指令 元素)。这是放置初始化代码的好地方 控制器。

所以在示例中:

app.component('formSelector', {
  bindings: {
    forms: '='
  },
  controller: function(FormSvc) {
    var ctrl = this;
    this.favorites = [];
    this.$onInit = function() {
      // At this point, bindings have been resolved.
      FormSvc
          .GetFavorites()
          .then(function(results) {
            ctrl.favorites = results;
            for (var i = 0; i < ctrl.favorites.length; i++) {
              for (var j = 0; j < ctrl.forms.length; j++) {
                if (ctrl.favorites[i].id == ctrl.newForms[j].id) {
                  ctrl.forms[j].favorite = true;
                }
              }
            }
          });
    }
}

所以是的,有一个 $onChanges(changesObj) ,但$onInit()专门解决了我们何时可以保证绑定已解决的原始问题。

我遇到了类似的问题,我发现这篇文章非常有帮助。http://blog.thoughtram.io/angularjs/2016/03/29/exploring-angular-1.5-lifecycle-hooks.html

我有一个 ajax 调用,它在页面加载时命中服务器,我的组件需要 ajax 返回值才能正确加载。我是这样实现的:

this.$onChanges = function (newObj) {
      if (newObj.returnValFromAJAX)
        this.returnValFromAJAX = newObj.returnValFromAJAX;
    };

现在我的组件运行良好。作为参考,我正在使用 Angular 1.5.6