Чи можу я отримати доступ до форми в контролері?


152

В даний час я використовую наступне.

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

Хтось має для цього рішення?

Відповіді:


210

Незважаючи на те, що нагадав в інших коментарях, я подумав, що трохи прописати його для тих, хто використовує синтаксис "Controller As":

<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();
       }
}

Наскільки я бачу, шаблон не може викликати метод "saveChanges", оскільки він не піддається впливу шаблону
Спок

2
Метод "saveChanges" відображається в рядку 3 JavaScript або я нерозумію?
slopapa

3
це добре, оскільки це означає, що ви можете уникнути введення цілого обсягу $, що на мою думку є чистішим
72GM

2
Як ви тестуєте це на жасмині? У моїй специфікації vm.myForm не визначено
bahrieinn

1
Це слід зазначити в офіційних документах для 1.5.X. Це спосіб зробити компоненти та es6. дякую, сер
MatanCo

91

Ви можете прикріпити форму до якогось об'єкта, який визначений у батьківському контролері. Тоді ви можете дійти до своєї форми навіть з дитячої сфери.

Батьківський контролер

$scope.forms = {};

Якийсь шаблон у дочірній області

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

Проблема полягає в тому, що форму не потрібно визначати в момент виконання коду в контролері. Тож ви повинні зробити щось подібне

$scope.$watch('forms.form1', function(form) {
  if(form) {
    // your code...
  }
});

10
Я б запропонував використовувати var watcher = $scope.$watcherі всередині оператора if, якщо ви виправдаєте спостерігача (), щоб відключити годинник. Це робить його одноразовим переглядом, тому ви не стежите за кожним дайджестом після його встановлення
willJk

91

Якщо ви хочете передати форму контролеру для цілей перевірки, ви можете просто передати її як аргумент методу обробки подання. Використовуйте назву форми, тому для оригінального питання це буде щось на кшталт:

<button ng-click="submit(customerForm)">Save</button>

13
Для того, щоб прояснити для читачів майбутніх, якщо сказати , ваша форма називається / визначається аналогічно цьому <form name="myform"></form>, або навіть <div ng-form name="myform"></div>, то ваше подія клацання буде виглядати наступним чином : ng-click="submit(myform)". Тоді ви можете отримати доступ до об'єкта Angular form у вашій функції натискання, наприклад: $scope.submit = function (form) { if (form.$valid) {etc.
Matty J

Я знаходжу тут проблему - скажімо, у формі є спадний список. Використання вищевказаного методу дає мені лише значення перегляду, а не точне значення, яке мені потрібно. Або я роблю щось не так, додамо загадку.
swateek

82

Трохи запізнився на відповідь, але прийшов із наступним варіантом. Це працює для мене, але не впевнений, правильно це чи ні.

На мій погляд, я роблю це:

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

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

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

Тепер після цього я отримав свою форму в змінній контролера, яка є $scope.myForm


1
Єдине, що я хотів би додати до цього, це переконатися, що це внизу форми.
smb

Положення <div ng-init = "setForm (formName);"> </div> не має значення. Тільки будьте уважні, щоб це було під формою.
waqas

1
добре, але я б віддав перевагу більш простому рішенню: ng-init = "$ parent.myForm = formName" Без необхідності зміни контролера. Примітка: він працює лише з прямим контролером, всупереч рішенню вище
mastilver

Спробувавши інші методи, я зупинився на цьому, оскільки він дозволяє nameатрибуту бути саме таким, яким я його хочу. Проблема з іншими рішеннями фіктивних об'єктів полягає в тому, якщо цей компонент використовується в іншому компоненті з формою ng, що інша форма ng використовує цю назву буквально. Тож у ньому буде поле з рядково-буквальним (НЕ вкладеним властивостями) ім'ям "dummy.myForm", я вважав це неприйнятним.
Василь

Я багато разів намагався використати синтаксис controllerAs (я працюю з $ mdDialog). Нарешті вирішив це, і це зробило чудову роботу. Зауважте лише, що будь-які ініціалізації контролера потрібно запускати на $ timeout, оскільки форма недоступна при першому запуску контролера
Peter Nixey

22

Щоб мати доступ до форми у вашому контролері, ви повинні додати її до об'єкта манекена.

Щось на зразок $scope.dummy = {}

Для вашої ситуації це означатиме щось на кшталт:

<form name="dummy.customerForm">

У своєму контролері ви зможете отримати доступ до форми:

$scope.dummy.customerForm

і ви зможете робити подібні речі

$scope.dummy.customerForm.$setPristine()

WIKI LINK

Маючи "." у ваших моделях гарантуватиме, що прототипне успадкування відтворюється. Отже, <input type="text" ng-model="someObj.prop1">скоріше використовуйте<input type="text" ng-model="prop1">

Якщо ви дійсно хочете / потребуєте використання примітиву, є два обхідні шляхи:

1.Використовуйте $ parent.parentScopeProperty у дочірній області. Це не дасть можливості дитині створити власну власність. 2.Визначте функцію в батьківській області та викличте її від дитини, передаючи примітивне значення до батьківського (не завжди можливо)


Де дієва область для визначення форми зв’язування?
Gus Crawford

варто згадати, що dummy.customerFormце буде невизначено до тих пір, поки не ng-ifбудуть виконані умови , якщо елемент форми має ng-ifна ньому
умовний характер

22

Ця відповідь трохи пізня, але я натрапив на рішення, яке робить все ЛОГО простішим.

Насправді ви можете призначити ім'я форми безпосередньо своєму контролеру, якщо ви використовуєте синтаксис controllerAs, а потім посилаєтесь на нього зі змінної "this". Ось як я це зробив у своєму коді:

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

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

а потім у HTML ви просто встановите назву форми як "контролерA". "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
            }
    }]);

2
Хоча це здебільшого та сама техніка, що підказує кілька інших відповідей, це найкраща варіація і повинна бути прийнятою відповіддю, тим більше, що зараз усі користуються контролерами.
Точка з комою

6

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

За винятком випадків, коли ваша форма не визначена в області контролера, а натомість визначена в дочірній області.

В основному, деякі кутові директиви, такі як ng-if, ng-repeatабо ng-include, створюватимуть ізольоване дочірнє поле. Як і будь-які власні директиви із scope: {}визначеним властивістю. Ймовірно, ваші компоненти фундаменту теж у вас на шляху.

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

Дивіться їх для отримання додаткової інформації:

Примітка: Я пропоную вам написати своє запитання. Відповідь на ваше запитання - так але ваша проблема трохи інша:

Чи можу я отримати доступ до форми у дочірній області від контролера?

На що відповідь була б просто: ні .


... якщо ви не встановите свої форми та контролер, як описано у відповіді @ondrs (використовуючи $scope.forms = {}та name="forms.form1")
marapet

Будь ласка, дивіться відповідь одразу над вашою від KhalilRavanna. Ви можете отримати доступ до форми з $ names.formName. Він наводить робочий приклад
micahblu

3

додайте ng-model="$ctrl.formName"атрибут до вашої форми, а потім у контролері ви можете отримати доступ до форми як об'єкта всередині вашого контролераthis.formName


0

Безумовно, ви не можете отримати доступ до форми в області застосування. вона не створена. Шаблон DOM з html завантажується трохи повільно, як конструктор контролера. рішення - дивитися, поки DOM не завантажиться і не буде визначено весь діапазон!

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

$timeout(function(){
    console.log('customerForm:', $scope.customerForm);
    // everything else what you need
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.