为什么在angular的控制器初始化期间form object不可用?

Why is form object not available during controller initialization in angular?

本文关键字:object form angular 控制器 初始化 为什么      更新时间:2023-09-26

考虑以下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 ?

我写错什么了吗?

父元素的控制器将在子元素之前创建并链接。如果您希望父元素知道子表单的信息,您可能需要这样做:

<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...
}

确定你想这么做吗?如果您的元素像这样与元素对话,这可能表示高耦合。你可能应该考虑用另一种方式进行交流;子组件告诉父组件变化。