Могу ли я получить доступ к форме в контроллере?

В настоящее время я использую следующее.

$scope.$$childHead.customerForm[firstName], чтобы:

<form name="customerForm">
  <input type="text" name="firstName" 
         ng-model="data.customer.firstName" 
         tabindex="1"  
         ng-disabled="!data.editable" 
         validationcustomer />
</form>

Но это работает только в Chrome. Теперь я попробовал следующее:

$scope.editCustomerForm[firstName], чтобы:

<form name="customerForm" ng-model="editCustomerForm">
  <input type="text" name="firstName" 
         ng-model="data.customer.firstName" tabindex="1"  
         ng-disabled="!data.editable" 
         validationcustomer />
</form>

Что не работает. Обратите внимание, что моя форма находится внутри вкладки Foundation. Как я могу получить доступ к firstName?

EDIT: похоже, что form не добавляется к scope, когда он находится внутри вкладки Foundation.

У кого-нибудь есть решение для этого?


person Vincent    schedule 24.10.2013    source источник


Ответы (9)


Хотя это упоминалось в других комментариях, я подумал, что немного разъясню это для тех, кто использует синтаксис «Контроллер как»:

<div ng-controller="MyController as ctrl">

<form name="ctrl.myForm">
    ...inputs
    Dirty? {{ctrl.myForm.$dirty}}

    <button ng-click="ctrl.saveChanges()">Save</button>
</form>

</div>

Затем вы можете получить доступ к FormController в своем коде, например:

function MyController () {
    var vm = this;
    vm.saveChanges = saveChanges;

    function saveChanges() {

       if(vm.myForm.$valid) { 
            // Save to db or whatever.
            vm.myForm.$setPristine();
       }
}
person slopapa    schedule 25.11.2014
comment
Насколько я вижу, шаблон не может вызвать метод saveChanges, так как он не доступен шаблону. - person Spock; 05.12.2014
comment
Метод saveChanges представлен в строке 3 javascript, или я неправильно понимаю? - person slopapa; 09.12.2014
comment
это хорошо, так как это означает, что вы можете избежать внедрения всей $scope, что, на мой взгляд, чище - person 72GM; 08.01.2015
comment
Как вы проверяете это в жасмин? В моей спецификации vm.myForm не определен - person bahrieinn; 20.11.2015
comment
Это должно быть отмечено в официальных документах для 1.5.X, что это способ делать компоненты и es6. Спасибо, сэр - person MatanCo; 28.05.2016
comment
попробовал это, но $valid, похоже, не работает с этим решением - person committedandroider; 29.11.2017
comment
У меня сработало, но мне пришлось изменить свою ng-форму на тег формы. - person linuxunil; 26.07.2018

Вы можете прикрепить форму к некоторому объекту, который определен в родительском контроллере. Затем вы можете добраться до своей формы даже из дочерней области.

Родительский контроллер

$scope.forms = {};

Некоторый шаблон в дочерней области

<form name="forms.form1">
</form>

Проблема в том, что форма не должна быть определена в момент выполнения кода в контроллере. Итак, вы должны сделать что-то вроде этого

$scope.$watch('forms.form1', function(form) {
  if(form) {
    // your code...
  }
});
person ondrs    schedule 09.04.2014
comment
Я бы предложил использовать var watcher = $scope.$watcher, а внутри оператора if вы должны выполнить watcher(), чтобы отвязать часы. Это делает просмотр 1 раз, поэтому вы не смотрите каждый дайджест после его установки. - person willJk; 22.06.2015

Если вы хотите передать форму контроллеру для целей проверки, вы можете просто передать ее в качестве аргумента методу, обрабатывающему отправку. Используйте имя формы, поэтому для исходного вопроса это будет что-то вроде:

<button ng-click="submit(customerForm)">Save</button>
person Anthony Shull    schedule 09.06.2014
comment
Чтобы уточнить для будущих читателей, если, скажем, ваша форма названа/определена аналогично этому <form name="myform"></form> или даже <div ng-form name="myform"></div>, тогда ваше событие клика будет следующим: ng-click="submit(myform)". Затем вы можете получить доступ к объекту формы Angular в своей функции щелчка, например: $scope.submit = function (form) { if (form.$valid) { и т. д. - person Matty J; 31.03.2015
comment
Я нахожу здесь проблему - допустим, в форме есть выпадающий список. Использование вышеуказанного метода дает мне только значение представления, а не точное значение, которое мне нужно. Или я что-то не так делаю, добавлю скрипку. - person swateek; 19.02.2016

Немного поздно для ответа, но пришел со следующей опцией. Это работает для меня, но не уверен, правильно это или нет.

На мой взгляд, я делаю это:

<form name="formName">
    <div ng-init="setForm(formName);"></div>
</form>

И в контроллере:

$scope.setForm = function (form) {
    $scope.myForm = form;
}

Теперь, после этого, у меня есть форма в моей переменной контроллера, которая равна $scope.myForm

person Atul Chaudhary    schedule 26.05.2014
comment
Единственное, что я бы добавил к этому, это убедиться, что это находится внизу формы. - person smb; 29.07.2014
comment
Позиция ‹div ng-init=setForm(formName);›‹/div› не имеет значения. Просто будьте осторожны, чтобы он был в форме. - person waqas; 19.09.2014
comment
хорошо, но я бы предпочел более простое решение: ng-init=$parent.myForm = formName Без необходимости смены контроллера Примечание: работает только с прямым контроллером, в отличие от решения выше - person mastilver; 18.11.2014
comment
Попробовав другие методы, я остановился на этом, потому что он позволяет атрибуту name быть именно таким, каким я хочу его видеть. Проблема с другими решениями для фиктивных объектов заключается в том, что если этот компонент используется в другом компоненте с ng-формой, эта другая ng-форма буквально использует это имя формы. Таким образом, у него будет поле со строковым литералом (НЕ вложенными свойствами) именем dummy.myForm, я нашел это неприемлемым. - person Basil; 15.07.2017
comment
Я много раз пытался и не смог использовать синтаксис controllerAs (я работаю с $mdDialog). В конце концов остановился на этом, и это отлично сработало. Единственное замечание: любые инициализации контроллера должны выполняться по тайм-ауту $, так как форма недоступна при первом запуске контроллера. - person Peter Nixey; 11.09.2019

Чтобы получить доступ к форме в вашем контроллере, вы должны добавить ее в фиктивный объект области видимости.

Что-то вроде $scope.dummy = {}

Для вашей ситуации это будет означать что-то вроде:

<form name="dummy.customerForm">

В вашем контроллере вы сможете получить доступ к форме:

$scope.dummy.customerForm

и вы сможете делать такие вещи, как

$scope.dummy.customerForm.$setPristine()

ССЫЛКА НА ВИКИ

Иметь '.' в ваших моделях гарантирует, что прототипное наследование будет в игре. Итак, используйте <input type="text" ng-model="someObj.prop1">, а не <input type="text" ng-model="prop1">

Если вы действительно хотите/нужно использовать примитив, есть два обходных пути:

1. Используйте $parent.parentScopeProperty в дочерней области. Это предотвратит создание дочерней областью собственного свойства. 2. Определите функцию в родительской области и вызовите ее из дочернего элемента, передав примитивное значение родительскому (не всегда возможно)

person Carsten    schedule 19.11.2014
comment
Где находится эффективная область для определения привязки формы? - person Gus Crawford; 03.09.2015
comment
стоит отметить, что dummy.customerForm будет неопределенным до тех пор, пока не будут выполнены условия ng-if, если элемент формы имеет условие ng-if для него. - person haxxxton; 25.05.2016

Этот ответ немного запоздал, но я наткнулся на решение, которое делает все НАМНОГО проще.

На самом деле вы можете назначить имя формы непосредственно вашему контроллеру, если вы используете синтаксис controllerAs, а затем ссылаетесь на него из своей «этой» переменной. Вот как я это сделал в своем коде:

Я настроил контроллер через ui-router (но вы можете сделать это как хотите, даже в HTML напрямую с чем-то вроде <div ng-controller="someController as myCtrl">) Вот как это может выглядеть в конфигурации ui-router:

views: {
            "": {
                templateUrl: "someTemplate.html",
                controller: "someController",
                controllerAs: "myCtrl"
            }
       }

а затем в HTML вы просто устанавливаете имя формы как «controllerAs». «name» следующим образом:

<ng-form name="myCtrl.someForm">
    <!-- example form code here -->
    <input name="firstName" ng-model="myCtrl.user.firstName" required>
</ng-form>

теперь внутри вашего контроллера вы можете очень просто сделать это:

angular
.module("something")
.controller("someController",
    [
       "$scope",
        function ($scope) {
            var vm = this;
            if(vm.someForm.$valid){
              // do something
            }
    }]);
person FrankieAvocado    schedule 21.03.2016
comment
Хотя это в основном та же техника, что и в нескольких других ответах, это лучший вариант и должен быть принятым ответом, тем более что сейчас все так или иначе используют контроллер. - person Semicolon; 28.03.2016

Да, вы можете получить доступ к форме в контроллере (как указано в документах ).

За исключением случаев, когда ваша форма не определена в области контроллера, а определена в дочерней области.

По сути, некоторые директивы angular, такие как ng-if, ng-repeat или ng-include, создают изолированную дочернюю область. Так же как и любые пользовательские директивы с определенным свойством scope: {}. Возможно, компоненты вашего фундамента также мешают вам.

У меня была та же проблема, когда я вводил простой ng-if вокруг тега <form>.

Смотрите их для получения дополнительной информации:

Примечание. Я предлагаю вам переписать свой вопрос. Ответ на ваш вопрос да, но ваша проблема немного отличается:

Могу ли я получить доступ к форме в дочерней области из контроллера?

На что ответ будет просто: нет.

person Andre Torgal    schedule 02.04.2014
comment
... если вы не настроили свои формы и контроллер, как описано в ответе @ondrs (используя $scope.forms = {} и name="forms.form1") - person marapet; 12.11.2014
comment
Пожалуйста, смотрите ответ KhalilRavanna сразу над вашим. Вы можете получить доступ к форме из $scope.formName. Он приводит рабочий пример - person micahblu; 17.07.2015

добавьте атрибут ng-model="$ctrl.formName" в свою форму, а затем в контроллере вы можете получить доступ к форме как к объекту внутри вашего контроллера с помощью this.formName

person Dhurim Kelmendi    schedule 07.03.2018

Определенно вы не можете получить доступ к форме в области видимости. он не создан. DOM из шаблона html загружается немного медленнее, чем конструктор контроллера. решение состоит в том, чтобы наблюдать, пока не загрузится DOM и не будет определена вся область!

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

$timeout(function(){
    console.log('customerForm:', $scope.customerForm);
    // everything else what you need
});
person Victor Orletchi    schedule 08.02.2017