Не удалось найти экземпляр FormController из родительской области

Проблема

Я пытаюсь получить доступ к экземпляру AngularJS FormController (созданному путем установки свойства name в директиве form) из области его родительского контроллера. Выход undefined.

Путаница

Но я вижу объект контроллера как свойство $scope, когда я вывожу его на консоль. Я также могу получить доступ к объекту из самого шаблона, используя директиву интерполяции.

Пример

Разметка выглядит так:

<body ng-controller="FooCtrl">
    <form name="FooForm" novalidate>
        <input name="bar" required>
    </form>
</body>

JavaScript выглядит примерно так:

myAngularApp.controller('FooCtrl', function ($scope) {
    console.log($scope.FooForm); // undefined
    console.dir($scope); // has FooForm peek-a-booing in there
});

Демо

Вот полный план: http://plnkr.co/edit/EE7pdBF32B5XRbjZuy8R?p=preview

Что я делаю не так? Я пытаюсь следовать этим документам: https://docs.angularjs.org/api/ng/directive/form



person Aditya M P    schedule 03.02.2015    source источник


Ответы (1)


Проблема здесь в том, что ваш контроллер инициализируется до вашего шаблона, поэтому в то время, когда вы пытаетесь его использовать, он все еще не определен. Попробуй это:

myApp.controller('MainCtrl', function ($scope) {
    $scope.$watch('NewForm', function () {
        var outputArea = document.getElementById('output-area');
        outputArea.innerHTML = "The FormController instance is: " + $scope.NewForm;
    });
});

Также обратите внимание, что использование:

outputArea.innerHTML = "The FormController instance is: " + console.dir(newVal);

Не имеет особого смысла, вы пытаетесь преобразовать возвращаемое значение console.dir в строку, которая также всегда возвращает undefined;) Изменено на:

outputArea.innerHTML = "The FormController instance is: " + $scope.NewForm;

Вот рабочий плункер: http://plnkr.co/edit/yfVP8hD6saWV2tIok2ER?p=preview

Изменить после комментария:

Если вы хотите получать уведомления, как только форма будет доступна в вашей области, и вы не хотите использовать $watch, вы можете сделать это, добавив пользовательскую директиву в элемент формы, который запускает событие:

<form name="NewForm" novalidate formready>

Пользовательская директива formready:

.directive('formready', function(){
    return {
        restrict: 'A',
        compile: function () {
            return {
                post: function(scope) {
                    scope.$emit('formready');
                }
            }
        }
    };
});

Теперь в вашем контроллере вы можете сделать:

$scope.$on('formready', function (event) {
    console.log($scope.NewForm); // Available now
});

Вот рабочий пример на Plunker: http://plnkr.co/edit/KG7LEB6EEkBkdONkL9LA?p=preview< /а>

person iH8    schedule 03.02.2015
comment
Спасибо за быстрый ответ! Приводит ли дополнительный $watch к снижению производительности? Есть ли способ избежать этого и при этом добиться того, что я пытаюсь? - person Aditya M P; 04.02.2015
comment
Я добавил код с другим примером, используя $emit, а не $watch. - person iH8; 04.02.2015
comment
Чего именно вы пытаетесь достичь, ссылаясь на форму таким образом? Не могли бы вы просто использовать ngModel в форме и использовать двухстороннюю привязку данных для доступа к значению в контроллере? - person smaira; 04.02.2015
comment
@smaira это было в основном для доступа к состоянию проверки формы в контроллере (в частности, к некоторым полям). - person Aditya M P; 04.02.2015
comment
Я понимаю. Возможно, ngMesssage может помочь с этим. - person smaira; 04.02.2015