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

Default ui-view content with directive using required causes error #1896

Closed
epelc opened this issue Apr 19, 2015 · 6 comments
Closed

Default ui-view content with directive using required causes error #1896

epelc opened this issue Apr 19, 2015 · 6 comments
Assignees
Labels
Milestone

Comments

@epelc
Copy link

epelc commented Apr 19, 2015

When using default ui-view content along with directives that use require the directives can't find the required controller and cause an error similar to the following.

https://docs.angularjs.org/error/$compile/ctreq?p0=mdTabs&p1=mdLabelTemplate

This can be seen in the latest version of angular-material if your using tabs but I'm sure many other libraries and custom directives make use of require.

@nateabele
Copy link
Contributor

Hm, interesting. Two recommendations: (1) try replacing your ui-view with a different directive that uses transclusion (i.e. ng-if or ng-repeat) and see if the effect is the same. If so, it's likely a bug with Angular Material. If not, post a reproduction of the issue in plunkr and I'll see what I can do. Thanks.

@eddiemonge
Copy link
Contributor

closing due to inactivity and missing plnkr

@jpekkala
Copy link
Contributor

Plunkr reproduction

This bug happens if the default content has an that loads a child directive. Everything works fine as long as the default content is shown but when you transition to a substate and the default content gets replaced with the substate's view, then the bug occurs.

@christopherthielen
Copy link
Contributor

interesting. Thanks for the plunker and explanation.

This might be challenging to track down the proper fix. Any thoughts @jpekkala ?

@jpekkala
Copy link
Contributor

The ctreq error occurs because the content is compiled without being attached to the DOM. There is a guard statement in ngInclude where it checks if its scope has already been destroyed when the asynchronous load finishes and it skips the compilation if that's the case. UI Router removes the default view content but does not destroy the scope that the default view (and ngInclude) uses.

This Plunkr illustrates the case. When you click the Substate button, two "created" messages are shown when the expected result should be either just one "created" message or two "created" messages and one "destroyed" message.

I haven't looked very carefully at UI Router's code yet but there are two solutions I can think of. Either skip compiling the default content altogether when a substate replaces the view or ensure that the default content uses its own scope that is destroyed before it is removed from the DOM. I can try to submit a patch later this week.

@christopherthielen
Copy link
Contributor

christopherthielen commented Nov 29, 2016

Note: this behavior is different in 1.0: https://plnkr.co/edit/LEjq0HP1b5vLUBVfxpSa?p=preview

In 1.0 the default directive destroyed message appears twice when activating the child.

christopherthielen pushed a commit that referenced this issue Nov 29, 2016
Previously the contents of the initial view were linked and left
undestroyed when the view was replaced with a subview. Because the view
was not destroyed, directives like ngInclude assumed it was safe to
compile and link asynchronous content to it. This would cause a ctreq
error if the asynchronous content required another directive from the
DOM. Now the initial view is either not linked at all or its scope is
properly destroyed.

Closes #1896
@christopherthielen christopherthielen added this to the 1.0.0-beta.4 milestone Nov 29, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants