【问题标题】:Why is binding value not available in controller immediately in angular为什么绑定值不能立即在控制器中以角度提供
【发布时间】:2017-06-04 23:25:38
【问题描述】:

我正在尝试将一些值绑定到控制器代码应该可用的 angular 1.6 组件中。

我一定是误会了,但是控制器运行时变量不可用。我管理它的唯一方法是通过 $timeout 将代码推送到下一个摘要周期。

我在这里做错了什么?

相关部分在这里:

var SelectorCtrl = ['$scope', '$http', '$timeout',
  function ($scope, $http, $timeout) {
    var self = this;
    alert("1: " + self.hierarchyId);

    // I'm not 100% sure why this has to be in the next digest cycle
    $timeout(function(){
      $scope.categories = self.categories;
      alert("2: " + self.hierarchyId);

    });
}

app.component('categorySelector', {
  templateUrl: 'categorySelector.html',
  controller: SelectorCtrl,
  bindings: {
    hierarchyId: "@",
    disabled: "=",
    categories: "=",
    onSelectionChanged: "&"
  }
});

请参阅 plunker:https://plnkr.co/edit/8rtDuCawdHaiXzQU5VBR

【问题讨论】:

  • 你为什么在同一个组件中混合$scopethis

标签: angularjs


【解决方案1】:

这是因为 Angular 1.6 中引入了 $compileProvider.preAssignBindingsEnabled(flag),您可以在 $compileProvider 的配置周期中配置它

如果禁用(false),编译器在调用之前先调用构造函数 分配绑定。

Angular 1.5.x 中默认值为 true,但在 Angular 1.5.x 中会切换为 false Angular 1.6.x.

您将在 Angular 组件的 $onInit 生命周期事件中获取所有绑定,其中所有绑定都可用(如果绑定同步传递)。

self.$onInit = function() {
  $scope.categories = self.categories;
  alert("2: " + self.hierarchyId);
};

注意:$scopethis 混合使用是不好的做法。而是避免使用$scope 使您的代码具有 Angular 2 迁移证明。


如果您希望在控制器函数实例化时绑定可用,那么您可以设置$compileProvider.preAssignBindingsEnabled(true)。这将使self.categories(bindings) 值。

app.config(function($compileProvider){
   $compileProvider.preAssignBindingsEnabled(true)
});

Similar answer


Angular 1.7.x 更新

从 Angular 1.7.x 开始,$compileProvider.preAssignBindingsEnabled(flag) 消失了,并且不再可能在构造函数之前分配绑定。

要解决这个问题,您需要在指令定义中定义一个link 函数。你可以让这个函数在你的控制器上调用一个方法,如下所示:

app.directive("directive", function() {
  return {
    controller: DirectiveController, // bind controller any way you want
    controllerAs: "ctrl",
    bindToController: true,
    link: function(scope) {
      scope.ctrl.init(); // this will call an init() function on your controller
    }
  }
});

【讨论】:

  • 好的,谢谢,不用担心会坚持$onInit。这里没有显示,但我使用的是 Devextreme UI 库(角度 1 集成),它在范围内查找它的值 - 所以需要将一个字符串传递给它们的组件,这是范围变量的名称。因此需要将值设置为范围。干杯。
  • @RichardG 你根本不需要使用$scope,你可以像$ctrl.categories一样将绑定传递给devexpress控件(它内部只存在于范围变量中)。我正在使用devexpresscontrollerAs 模式。它运作良好:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-18
  • 2012-04-01
  • 1970-01-01
  • 2017-01-26
  • 1970-01-01
相关资源
最近更新 更多