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

tcm*_*ore 35 javascript components angularjs

我正在写一个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
      }
     }
    })
}
...
Run Code Online (Sandbox Code Playgroud)

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

问题是,即使在填充绑定之前,承诺仍在实现......所以当我运行循环时,ctrl.forms仍未定义!

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

Ced*_*Ced 34

我有一个类似的问题,我这样做是为了避免调用组件,直到我要发送的值准备就绪:

<form-selector ng-if="asyncValue" forms="asyncValue" ></form-selector>
Run Code Online (Sandbox Code Playgroud)

  • 这是一个优雅的解决方案. (3认同)

Cos*_*bei 28

您可以使用新的生命周期钩子,特别$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>
Run Code Online (Sandbox Code Playgroud)

  • 真棒!非常感谢.Angular现在在一个奇怪的地方; 对于以1.3或1.4开始的应用程序来说,1.5是如此酷,非常棒的选择......但是当您在1.5组件上搜索帮助时,很难对所有Angular 2社区聊天进行排序! (6认同)

Oli*_*Oli 7

原来的海报说:

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

自从AngularJS 1.5.3以来,我们有生命周期钩子并且为了满足OP的问题,你只需要根据内部满足的绑定移动代码$onInit():

$ onInit() - 在构造了元素上的所有控制器并初始化其绑定之后(在此元素上的指令的前后链接函数之前),在每个控制器上调用.这是为控制器放置初始化代码的好地方.

所以在这个例子中:

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;
                }
              }
            }
          });
    }
}
Run Code Online (Sandbox Code Playgroud)

所以是的,有一个$onChanges(changesObj),但$onInit()具体地解决了原来的问题,我们什么时候能得到绑定已经解决的保证.