为什么在控制器初始化期间表格对象不可用?

时间:2016-09-20 19:19:01

标签: javascript angularjs

考虑以下html

<div ng-app="myApp" ng-controller="myController">
    <form name="myForm"></form>
</div>

和控制器文件

(function () {
    'use strict';

    angular
        .module('myApp')
        .controller('myController', myController);

    myController.$inject = ['$scope', '$interval'];

    function myController($scope, $interval) {
        var myFormDetector = $interval(function() {
            if ($scope.myForm) {
                console.log('form exist');
                $interval.cancel(myFormDetector);
            } else {
                console.log('form not exist');
            } 

        }, 200)
    }
})();

我发现form not exist至少打印一次?

这很奇怪,因为我认为渲染的顺序是

compile
controller
link

所以当controller初始化时,compile应该渲染html并注入$scope

我有什么不对吗?

1 个答案:

答案 0 :(得分:1)

将在子元素之前创建并链接父元素的控制器。如果您希望父元素知道子表单,您可能希望执行以下操作:

<div ng-app='myApp' ng-controller='myController'>
  <form name='myForm' ng-init='myController.onInit()'>
  </form>
</div>
function MyController($scope) {
  this.$scope = $scope
}

MyController.prototype.onInit = function onInit() {
  this.$scope.myForm....
}

虽然这不是很可持续,但使用ngController这样的做法被认为是不好的做法。这种模式很常见,事实上很常见的是Angular为它的组件绑定了(Angular 1.5 +)

<div ng-app='myApp'>
  <x-parent-component>
    <form name='ngForm'>
    </form>
  </x-parent-component>
</div>
angular.module('myApp', [])
  .component('xParentComponent', {
    controller: XParentComponentCtrl,
    transclude: true,
    template: '<div ng-transclude></ng-transclude>'
  })

function XParentComponentCtrl($scope) {
  this.$scope = $scope
}
XParentComponentCtrl.prototype.$postLink = function $postLink() {
  this.$scope.myForm...
}

确定你想要这样做吗?如果你的元素与这样的 child 元素对话,它可能表示高耦合。你应该考虑让沟通成为另一种方式; 组件告诉组件有关更改。