Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded forms aren't attached to $scope #8403

Closed
metric152 opened this issue Jul 29, 2014 · 3 comments
Closed

Embedded forms aren't attached to $scope #8403

metric152 opened this issue Jul 29, 2014 · 3 comments

Comments

@metric152
Copy link

@metric152 metric152 commented Jul 29, 2014

When a form is inside a ng-directive include it's not attached to the $scope object.

I go into detail about it here
http://blog.152.org/2014/07/angular-form-element-not-attaching-to.html

@caitp
Copy link
Contributor

@caitp caitp commented Jul 30, 2014

So, the issue you're describing is really just a misunderstanding about the way scopes in Angular work. It's a bit of a tricky system and admittedly takes some getting used to, but this is working as expected.

ng-controller will create a new scope, as will ng-include whenever it adds a template to the DOM.

So what you end up with is a scope hierarchy like this:

  002 - rootScope
         003 - ngController
                004 - ngInclude

The included form directive adds createUser to the ngInclude scope (called 004 in the chart above, but the IDs in a real application won't necessarily match). You can't get at this via scope003.createUser, because it's lower in the scope hierarchy, you'd have to grab the child scope and get it that way (not recommended).

There are work arounds for this, for instance:

<div ng-controller="controllerName" ng-init="forms = {}; model = {}">
    <div ng-include=" 'path-to-the-template' "></div>
</div>

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

This will put the included form in scope003.forms.createUser, and will put the name and email inputs in scope003.model.name and scope003.model.email, respectively. Note, you don't necessarily have identifiers for scope003 declared, this is just indicating that it's in the controller's scope.

Here's an example: http://jsfiddle.net/g8DkL/

This might seem inconvenient, but it's really what you want to do anyways, so that you avoid confusion when new scopes are created that you aren't aware of.

So I don't think we're going to call this a bug, but it is clearly one of those hurdles that you need to jump over while learning the framework, and it is understandably frustrating =)

@caitp
Copy link
Contributor

@caitp caitp commented Jul 30, 2014

The reasons why this works this way make sense if you understand prototypical inheritance in javascript (child scopes prototypically inherit from their parent scopes, so scope004.proto === scope003, and scope003.proto === scope002, etc), so if it's unclear from this explanation and example, I suggest reading up on resources regarding that, including https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain

@metric152
Copy link
Author

@metric152 metric152 commented Jul 30, 2014

Once you said the include will have its own scope my problem made complete sense. I didn't realize that was the case. Thank you so much for the help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.