Подтвердить что ты не робот

Простая форма AngularJS undefined в области

Я начинаю играть с формами AngularJS в jsfiddle, и я столкнулся с проблемой уже там, где очень простой пример формы работает не так, как ожидалось. Все, что у меня есть, - это именованная форма, и по какой-то причине она не появляется (я ожидаю экземпляр FormController).

У меня есть fiddle, и ниже приведен базовый код:

HTML

<div id="mainContainer" ng-app="angularTest" ng-controller="MainCtrl">
    <h1>The Form</h1>
    <form name="theForm">
        <input name="myName" type="text" ng-model="model.name" />
        <input name="submit" type="submit" />
    </form>
</div>

JS

var app = angular.module('angularTest', []);

app.controller('MainCtrl', ['$scope', function($scope) {
    $scope.model = { name: 'Model Name' };
    console.log($scope.theForm); //displays 'undefined'
}]);

Я не могу найти много простых примеров этого на jsfiddle, поэтому я не был уверен, что это может быть странное взаимодействие с такими сайтами (большинство примеров, которые я нахожу, не используют формальные контроллеры). Я тоже пробовал на Plunker, но я столкнулся с той же проблемой.

Я уверен, что мне не хватает чего-то сверх очевидного, но я не вижу много другого, чтобы изменить или настроить здесь. Любая помощь очень ценится!

4b9b3361

Ответ 1

Форма регистрируется только с $scope контроллера после того, как контроллер изначально запускался. Поэтому console.log($scope.theForm) вернет undefined, даже если все настроено правильно.

В вашем примере, чтобы реагировать на присутствие theForm, вы можете настроить наблюдателя на theForm, чтобы установить текст отладки в зависимости от его присутствия:

$scope.$watch('theForm', function(theForm) {
    if(theForm) { 
        $scope.formDebugText = 'Form in Scope';
    }
    else {
        $scope.formDebugText = 'Form is Undefined';
    }        
});

который можно увидеть в действии на http://jsfiddle.net/9k2Jk/1/

Ответ 2

Хороший способ выполнить это без использования чата (который немного перебор) - это определить объект в области, в которую вы зарегистрируете форму.

HTML

<div id="mainContainer" ng-app="angularTest" ng-controller="MainCtrl">
    <h1>The Form</h1>
    <form name="form.theForm">
        <input name="myName" type="text" ng-model="model.name" />
        <input type="button" value="Here the scope" ng-click="display()"/>
        <input name="submit" type="submit" />
    </form>
</div>

JS

var app = angular.module('angularTest', []);

app.controller('MainCtrl', ['$scope', function($scope) {
    $scope.model = { name: 'Model Name' };
    $scope.form = {};
    $scope.display = function () {
        console.log($scope.form.theForm);
    }
}]);

Ответ 3

Для меня было исправлено использование родительского объекта в $scope.

В контроллере:

$scope.forms = {};
$scope.registerUser = function registerUser() {
    if ($scope.forms.userForm.$valid) {
        alert('submit');
    }
};

В шаблоне:

<form name="forms.userForm" ng-submit="registerUser()">

Причина:

Если вы используете <form name="userForm"... вместо <form name="forms.userForm"..., он прикрепляет форму к дочерней области, но поскольку $scopes использует прототипическое наследование, как только я объявляю пустой литерал объекта в исходном $scope, форма была присоединена к вместо этого.

Ответ 4

Это рекомендуемый способ доступа к переменной формы: https://docs.angularjs.org/guide/forms - Связывание для формирования и управления состоянием

В HTML:

<form name="form">  
<input type="button" ng-click="reset(form)" value="Reset" />
</form>

Youl передаст имя формы как переменную функции.

В JS:

$scope.reset = function(form) { 
  alert(form); 
};

Переменная "форма" НЕ должна быть undefined.

Ответ 5

В моем случае я использовал ng-include для создания поддиапазона, поэтому в текущей области видимости свойство undefined, чтобы быть безопасным и предотвратить проблему с дополнительными областями, мы должны использовать переменную переменной, чтобы назвать форму, как form.theForm.

Но убедитесь, что вы заранее объявили это имя формы в своем контроллере.

<form name="form.theForm">
    <input name="myName" type="text" ng-model="model.name" />
    <input name="submit" type="submit" />
</form>

app.controller('MainCtrl', ['$scope', function($scope) {
    $scope.model = { name: 'Model Name' };
    //You have to declare here, else it will trigger undefined error still.
    $scope.form = {
      theForm: {} 
    };

    $scope.reset = function(){
       $scope.form.theForm.$setPristine();
    }
}]);

Ответ 6

Вы можете повторно инициализировать форму с вашего контроллера, прежде чем пытаться получить доступ к $scope.form с помощью этой строки кода. $scope.form будет доступен.

angular.element(jQuery('.form-control')).triggerHandler('input')

Ответ 7

Я написал директиву для решения этой проблемы. Его атрибут, который вы можете наложить на свою форму и передать функцию, которая будет выполняться, когда форма готова.

Javascript

angular.module('app').directive('formInit', function(){
  return {
    restrict: 'A',
    scope: {
      init: '&formInit'
    },
    controller: function($scope, $element){
      var name = null;
      if ($element[0] && $element[0].name){
        name = $element[0].name;
      }

      var listener = $scope.$watch('init', function(){
        if ($scope[name] && $scope.init){
          $scope.init();
          listener();
        }
      });
    }
  };
});

Пример HTML

<form name="test" form-init="testing()">

Где testing - функция в области вашего контроллера.