Why form undefined inside ng-include when checking $pristine or $setDirty()?

梦想与她 提交于 2019-11-27 08:36:00
miensol

To understand why the solution with formHolder work you have to understand JavaScript prototypes chain first. Let's illustrate the first case without formHolder in the following pseudo code:

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

When the form directive is parsed it creates FormController which is set on the $scope property under key indicated in name attribute value. This is pretty much equivalent to:

$childScope.productForm = $formCtrl;

After which the 2 scopes look like this:

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

So you actually ended up with 2 properties on different scopes holding different objects. Now in the second case you have the following situation:

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

When the form directive is setting FormController instance on the $scope this time it uses different property chain:

$childScope.formHolder.productForm = $formCtrl;

Which is equivalent to writing:

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;

Hope it helps to understand why the second option works. As for the second part of you question - your solution is simple and perfectly viable - but there are couple of other ways to handle it which is best depends on the actual usage context:

  • using directive without child scope to extract common markup and parts of functionality
  • using directive with child scope that would communicate state changes either via direct parent scope property access or via emitted events
  • using a custom include directive that would not create child scope

Just define the variable (empty object) in the controller and use it while defining your form. Since angular JS uses scope prototypes under the hood, when form will try to access the inner scope (to bootstrap the variable), it will first go via scope chain and try to find the same variable in the parent's scope.

<!—- 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>

Link for reference http://blog.152.org/2014/07/angular-form-element-not-attaching-to.html

I know that this is a old question, but i had a similar problem, and i changed the html and included my ng-controller within the html file.

So instead of

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

Change it too

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

And then in the myForm.html file, wrap the code in a div, and add the ng-controller attribute, so your myForm.html would become

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

Now your child controller is within the ng-include scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!