source

$pristine 또는 $setDirty()를 확인할 때 내부 ng를 포함한 폼이 정의되지 않은 이유는 무엇입니까?

manycodes 2023. 9. 23. 22:51
반응형

$pristine 또는 $setDirty()를 확인할 때 내부 ng를 포함한 폼이 정의되지 않은 이유는 무엇입니까?

"체크" 버튼을 클릭하면 다음 코드에서 "TypeError: 정의되지 않은 '$pristine' 속성을 읽을 수 없습니다"라는 오류가 발생합니다.

app.controller('MainCtrl', function($scope) {
  // other stuff
})

.controller('Ctrl2', function($scope) {
  $scope.product = {description:'pump'};
  $scope.output = 'unknown';
  // uncomment to avoid undefined error, still can't see $pristine
  // $scope.formHolder = {};
  $scope.checkForm = function() {
    $scope.descriptionTest = $scope.product.description;
    if ($scope.formHolder.productForm.$pristine) {
      $scope.output = 'yes';
    }
    if ($scope.formHolder.productForm.$dirty) {
      $scope.output = 'no' 
    }
  }
});

html

  <body ng-controller="MainCtrl">
    <div >
      <ng-include ng-controller="Ctrl2" src="'myForm.html'"></ng-include>
    </div>
  </body>

myForm.html

<form name="productForm" novalidate>
  <h2>myForm</h2>
  description: <input type="text" name="description" ng-model="product.description"/>
  <br>
  <button ng-click="checkForm()">Check Form</button>
  <br>
  Form Pristine: {{output}}
  <br><br>
  I can see the description: {{descriptionTest}}
</form>

플렁커

문제는 제 Ctrl2가 제품 양식을 볼 수 없다는 것입니다.처음에 저는 이것이 ng-include가 하위 범위를 만들 때 하는 것을 프로토타입이 물려받는 것과 관련이 있다고 생각했습니다. 그래서 Ctrl2에 변수를 추가하려고 했습니다.

$scope.productForm = {}; 

이것은 오류를 제거했지만, 컨트롤러가 $prinstein 또는 $dirty를 제대로 인식하지 못했습니다.

드디어 $scope을 추가해서 작동하게 되었습니다.제품 위의 formHolder 개체 양식:

플렁커

.controller('Ctrl2', function($scope) {
  $scope.product = {description:'pump'};
  $scope.output = 'unknown';
  // uncomment to avoid undefined error, still can't see $pristine
  $scope.formHolder = {};
  $scope.checkForm = function() {
    $scope.descriptionTest = $scope.product.description;
    if ($scope.formHolder.productForm.$pristine) {
      $scope.output = 'yes';
    }
    if ($scope.formHolder.productForm.$dirty) {
      $scope.output = 'no' 
    }
  }
});

html

<form name="formHolder.productForm" novalidate>

이게 왜 되는 거지?더 나은 방법이 있을까요?

다른 곳에서 재사용하고 싶은 작업 양식과 컨트롤러/템플릿이 있어서 이렇게 하게 되었습니다.제가 지시를 내려야 할 것 같은데, 양식의 $pirstine과 $dirty 기능을 제외하고는 모든 것이 정상적으로 작동했습니다. 모든 ng-model vars가 올바르게 통과되었습니다.

엔지 인크루드 내부에 포함된 폼을 프레스틴으로 설정하려면 어떻게 해야 합니까?"모든 규칙을 breaks하라"는 대답이 있지만 더 복잡해 보였습니다.

컨트롤러 양식을 작성할 때 범위에 $prinestine을 추가하는 경우와 범위는 무엇입니까?

편집 / 답변:

제 원래 질문은 양식 지침이 범위에 어떻게 쓰이는지에 대한 혼란으로 요약될 수 있습니다.나는 그것이 그것을 받아들일 것이라는 인상을 받았습니다.

<form name="productForm">...

거기에 속성을 추가하는 거죠, 예를 들어요.

$scope.productForm.$pristine = function() {...}

그러나 제품 위에 직접 적습니다. 양식:

$scope.productForm = formObject;

따라서 양식 개체는 선택한 답변에서 설명한 부모가 아닌 자식에 저장됩니다.

제가 도움이 된 자녀 범위 상속의 핵심 너겟은 체인이 읽기에서는 상담을 받지만 쓰기에서는 상담을 받지 않는다는 것입니다.그래서 childScope.m 같은 것을 설정하면,yThing.property = '123'은 쓰기처럼 보이지만 먼저 읽기를 수행해야 내 Thing이 무엇인지 알 수 있습니다.childScope.m을 설정하는 동안yThing = '567'은 직접 쓰기이며 상위 체인을 보는 것과 전혀 관련이 없습니다.AngularJS에서 스코프 프로토타입/원형 상속의 뉘앙스는 무엇입니까?에서 더 잘 설명됩니다.

솔루션을 사용하는 이유를 이해하기 위해formHolder먼저 자바스크립트 프로토타입 체인을 이해해야 합니다.첫 번째 사례를 설명해 보겠습니다.formHolder다음 의사 코드에서:

$parentScope = {
  //I'm a parent scope inside Ctrl2
  productForm:{} //to avoid undefined reference error 
}

$childScope = {
  //I'm a child scope created by by ng-include 
  __protototype__: $parentScope 
}

언제.form지시문은 구문 분석됩니다.FormController그것은.$scope에 표시된 키 아래의 재산name속성 값.이는 다음과 같습니다.

$childScope.productForm = $formCtrl;

그 다음 두 스코프는 다음과 같습니다.

$parentScope = {
  //I'm a parent scope inside Ctrl2
  productForm:{} //to avoid undefined reference error 
}

$childScope = {
  //I'm a child scope created by by ng-include 
  productForm: $formCtrl

  __protototype__: $parentScope 
}

따라서 실제로 서로 다른 물체를 잡고 있는 서로 다른 스코프에 두 개의 속성을 갖게 되었습니다.두 번째 경우에는 다음과 같은 상황이 발생합니다.

$parentScope = {
  //I'm a parent scope inside Ctrl2
  formHolder:{} //to avoid undefined reference error 
}

$childScope = {
  //I'm a child scope created by by ng-include 
  __protototype__: $parentScope 
}

언제.form지시가 설정 중입니다.FormController에 대한 예.$scope이번에는 다양한 속성 체인을 사용합니다.

$childScope.formHolder.productForm = $formCtrl;

글을 쓰는 것과 맞먹는 것:

var formHolder = $childScope.formHolder; //since formHolder isn't defined on $childScope
//the JS runtime will look for it in the prototypes chain and find it inside $parentScope
//so here formHolder is the very same object you created and set on $parentScope
formHolder.productForm = $formCtrl;

두 번째 옵션이 작동하는 이유를 이해하는 데 도움이 되기를 바랍니다.질문의 두 번째 부분인 솔루션은 단순하고 완벽하게 실행 가능합니다. 하지만 실제 사용 상황에 따라 최적으로 대처할 수 있는 몇 가지 방법이 있습니다.

  • 하위 범위 없이 지시를 사용하여 공통 마크업 및 기능의 일부를 추출합니다.
  • 직접 부모 범위 속성 액세스 또는 방출된 이벤트를 통해 상태 변화를 전달하는 하위 범위와 함께 지시 사용
  • 사용자 정의 사용 하위 범위를 만들지 않는 지시 포함

저는 이것이 오래된 질문이라는 것을 알고 있지만, 비슷한 문제가 있었고, html을 변경하고 html 파일에 ng-controller를 포함시켰습니다.

그래서 대신에.

<ng-include ng-controller="Ctrl2" src="'myForm.html'"></ng-include>

그것도 바꿉니다.

<ng-include="'myForm.html'"></ng-include>

그런 다음 myForm.html 파일에서 코드를 div로 래핑하고 ng-controller 속성을 추가하면 myForm.html은 다음과 같이 됩니다.

<div ng-controller="Ctrl2">
    <form name="productForm" novalidate>
      <h2>myForm</h2>
      description: <input type="text" name="description" ng-model="product.description"/>
      <br>
      <button ng-click="checkForm()">Check Form</button>
      <br>
      Form Pristine: {{output}}
      <br><br>
      I can see the description: {{descriptionTest}}
    </form>
</div>

이제 자식 컨트롤러가 ng 포함 범위 내에 있습니다.

컨트롤러에 변수(빈 개체)를 정의하고 양식을 정의할 때 사용하면 됩니다.각진 JS는 후드 아래에 스코프 프로토타입을 사용하므로 폼이 (변수를 부트스트랩하기 위해) 내부 스코프에 액세스하려고 할 때 먼저 스코프 체인을 거쳐 상위 스코프에서 동일한 변수를 찾으려고 시도합니다.

<!—- The vars should live in the controller. I placed them here for the example. -—>
<div ng-controller=“controllerName” ng-init="form={}; model={}" >
    <div ng-include=“ ‘path-to-the-template’ ”></div>
</div>

<!—- Inside path-to-the-template -—>
<form name="form.createUser">
    <input name="name" ng-model="model.name" />
    <input name="email" ng-model="model.email" />
</form>

참고용 링크 http://blog.152.org/2014/07/angular-form-element-not-attaching-to.html

언급URL : https://stackoverflow.com/questions/23686831/why-form-undefined-inside-ng-include-when-checking-pristine-or-setdirty

반응형