컨트롤러에서 양식에 액세스 할 수 있습니까?


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있습니까?

편집 : Foundation 탭 안에있을 때 form추가되지 않은 것처럼 보입니다 scope.

누구든지 이것에 대한 해결책을 가지고 있습니까?

답변:


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"메소드를 호출 할 수 없습니다
Spock

2
"saveChanges"메소드가 자바 스크립트의 3 행에 노출되어 있거나 잘못 이해하고 있습니까?
slopapa

3
이것은 내 생각에 더 깨끗한 $ scope 전체를 주입하는 것을 피할 수 있다는 것을 의미하기 때문에 좋습니다
72GM

2
자스민에서 이것을 어떻게 테스트합니까? 내 사양에 따르면, vm.myForm은 정의되어 있지 않습니다
bahrieinn

1
이것은 구성 요소와 es6을 수행하는 방법 인 1.5.X의 공식 문서에서 언급해야합니다. 감사합니다
MatanCo

91

부모 컨트롤러에 정의 된 일부 개체에 양식을 첨부 할 수 있습니다. 그러면 하위 범위에서도 양식에 도달 할 수 있습니다.

부모 컨트롤러

$scope.forms = {};

하위 범위의 일부 템플릿

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

문제는 컨트롤러에서 코드를 실행할 때 양식을 정의 할 필요가 없다는 것입니다. 그래서 당신은 이런 식으로해야합니다

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

10
var watcher = $scope.$watcherif 문을 사용 하고 내부에서 watcher ()를 실행하여 시계를 바인딩 해제하는 것이 좋습니다. 이것은 당신이 설정 한 후 모든 소화보고하지 않는, 그래서 1 시간 시계합니다
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 양식 객체에 액세스 할 수 있습니다 $scope.submit = function (form) { if (form.$valid) {.
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
좋은,하지만 난 간단한 솔루션을 선호하는 것 : 겨-INIT = "$ parent.myForm =는 FormName"필요는 컨트롤러 참고 변경 Whithout : 만 직접 컨트롤러, 위의 솔루션에 반하는으로 일하고있어
mastilver

다른 방법을 시도한 후에는 name속성이 내가 원하는 그대로 될 수 있기 때문에이 방법을 사용 했습니다. 다른 더미 오브젝트 솔루션의 문제점은이 구성 요소가 다른 구성 요소에서 ng 양식을 사용하는 경우 다른 ng 양식이이 양식 이름을 문자 그대로 사용한다는 것입니다. 따라서 문자열 문자 (중첩 속성이 아님) 이름이 "dummy.myForm"인 필드가 있으므로 허용되지 않습니다.
Basil

controllerAs 구문을 사용하려고 여러 번 시도하고 실패했습니다 ($ mdDialog로 작업 중). 마침내 이것을 위해 정착했고 훌륭한 일을했습니다. 단지 컨트롤러가 처음 실행될 때 폼을 사용할 수 없기 때문에 모든 컨트롤러 초기화는 $ timeout에서 실행되어야합니다.
Peter Nixey

22

컨트롤러에서 폼에 액세스하려면 더미 스코프 객체에 폼을 추가해야합니다.

같은 것 $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를 사용하십시오. 이렇게하면 자식 범위가 자체 속성을 만들 수 없습니다. 부모 범위에서 함수를 정의하고 자식에서 호출하여 기본 값을 부모에게 전달하십시오 (항상 가능한 것은 아님)


양식 바인딩을 정의하기위한 유효 영역은 어디에 있습니까?
거스 크로포드

양식 요소에 조건 이있는 경우 조건 이 충족 dummy.customerForm될 때까지 정의되지 않음을 언급 할 가치 가 있습니다.ng-ifng-if
haxxxton

22

이 답변은 약간 늦었지만 모든 것을 훨씬 쉽게 만드는 솔루션을 발견했습니다.

controllerAs 구문을 사용하는 경우 실제로 폼 이름을 컨트롤러에 직접 할당 한 다음 "this"변수에서 참조 할 수 있습니다. 코드에서 수행 한 방법은 다음과 같습니다.

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

2
이것은 대부분 다른 답변이 제안하는 것과 동일한 기술이지만, 가장 좋은 변형이며 특히 모든 사람이 controllerA를 사용하기 때문에 허용되는 답변이어야합니다.
세미콜론

6

예, 컨트롤러에서 양식에 액세스 할 수 있습니다 ( docs에 설명 된대로 ).

양식이 컨트롤러 범위에 정의 되지 않고 대신 하위 범위에 정의 된 경우를 제외하고 .

기본적으로, 어떤 각도 지시어는 같은 ng-if, ng-repeat또는 ng-include, 격리 된 자식 범위를 만들 것입니다. scope: {}속성이 정의 된 모든 사용자 지정 지시문도 마찬가지입니다 . 아마도 기초 구성 요소도 방해가 될 수 있습니다.

태그 ng-if주위 에 간단한 것을 소개 할 때도 같은 문제가있었습니다 <form>.

자세한 내용은 다음을 참조하십시오.

참고 : 질문을 다시 작성하십시오. 귀하의 질문에 대한 답변은 이지만 귀하의 문제는 약간 다릅니다.

컨트롤러에서 하위 범위의 양식에 액세스 할 수 있습니까?

대답은 간단합니다 : no .


... @ondrs 'answer ( $scope.forms = {}및 사용 name="forms.form1")에 설명 된대로 양식과 컨트롤러를 설정하지 않는 한
marapet

KhalilRavanna의 답변 바로 위를 참조하십시오. $ scope.formName에서 양식에 액세스 할 수 있습니다. 그는 실제 사례를 제공합니다
micahblu

3

ng-model="$ctrl.formName"폼 에 속성을 추가 한 다음 컨트롤러에서 컨트롤러 내부의 객체로 폼에 액세스 할 수 있습니다this.formName


0

확실히 당신은 범위 bec의 양식에 액세스 할 수 없습니다. 작성되지 않습니다. html 템플릿의 DOM은 컨트롤러 생성자처럼 조금 느리게로드됩니다. 해결책은 DOM 이로 드되고 모든 범위가 정의 될 때까지 감시하는 것입니다!

컨트롤러에서 :

$timeout(function(){
    console.log('customerForm:', $scope.customerForm);
    // everything else what you need
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.