-
Notifications
You must be signed in to change notification settings - Fork 27.5k
Make include works better with primitive $scope values #943
Comments
I wish we could but it isn't possible with the current scope design as this is how the prototypical inheritance in javascript works. scopes prototypically inherit form each other, and when you set a property on a child it doesn't update the existing property of the parent. we are thinking about ways we could help people avoid this trap, but in a short term, best practice guidelines seem to be the only feasible way. As you observed binding to objects instead of primitives avoids this issue and that's exactly what we suggest that people do in their apps. Additionally instead of using ngInclude which always creates a new scope (to prevent memory leaks). We should provide a "static" ngInclude alternative, which doesn't need to be concerned about memory leaks and thus doesn't need to create a new scope. Until this is part of the core framework, you can create this directive with just a few lines of code. By static I mean that the template src is a constant rather than a bound variable:
|
How about optionally passing a scope to ng-include (I think that's how it was a while back in angulars history). So one could do |
Or how about that: All properties will by default be moved one level down. So it's
instead of just:
But in the directives one can omit the data to just bind to "foo" as we do today. |
if the scope is passed in and your app doesn't do the create new scope/destroy old scope dance, newly compiled templates are linked against a single scope and with that all of the old bindings found in old templates are still registered with this scope. the whole scope nesting thing is Angular's way of creating garbage collection boundaries in the app, which allows us to clean up the memory easily by just destroying the appropriate scope. |
I like the The downsides are:
|
Given the difficulty of |
One more option, to add to a long-dead thread: a common use case I'm seeing is to include a partial where the |
The "controller as" syntax helps quite a bit. http://docs.angularjs.org/api/ng.directive:ngController#usage_directive-info_parameters Closing this issue. If anyone has a concrete suggestion for improving this, feel free to open a new issue describing it. Thanks! |
I was looking for a solution to this issue, and figured one out on my own. Since the addition of ng-if, a simple trick to ensure your scope gets passed is to :
(Assuming you set your object to null in the parent controller) This will generate a new scope which can be used with your data. Might be worth noting that the scope is only passed on creation of the include scope... so you'll lose data if you're performing an http request or something beforehand. This behavior is also strange, and I had a hard time tracking this down because when I loaded a page directly, there would seem to be no issue. But when going to a new route from an old route, the template was cached, and loaded immediately, missing my request information. It would be nice if the new scope created in an ng-include $watched the $parent scope for changes, and copied them over. |
Anyway possible to use object like |
Here is the problem:
When you use ng-include people are assuming that the view that is included has full access to everything the parent view has. In fact it has! However, ng-include creates a new scope and therefore all the primitive values on the parent scope become readonly values for the included view.
The problem is illustrated here: http://jsfiddle.net/cburgdorf/PMc69/1/
The textbox should update the div but it isn't.
It's fixable by wrapping your primitive with an object like so:
http://jsfiddle.net/cburgdorf/RwWs3/2/
However, that's cumbersome and counterintuitive. Can we fix that?
The text was updated successfully, but these errors were encountered: