dotJEM / angular-routing

Enhanced state based routing for Angular applications!
https://dotjem.github.io/angular-routing/
MIT License
75 stars 9 forks source link

Avoid race in jem-view when scope is destroyed before template is loaded #130

Closed groner closed 9 years ago

groner commented 9 years ago

We ran into this in our application when we redefined a mid level view for a state to use a custom controller, but the same template. I think there is a transition in effect that could be playing a part in the timing.

The following is pseudo-code that attempts to describe the situation. I'll work on getting a working demonstration and/or test case.

$state
.state('top', {
  route: '',
  views: {
    middle: { template: 'middle.html' },
    header: template: 'header.html' },
  },
})
.state('top.foo', {
  route: 'foo',
  views: {
    // The foo module is pretty simple and fits into one view
    main: { template: 'foo.html', controller: 'FooCtrl' },
  },
})
.state('top.bar', {
  route: 'bar',
  views: {
    // The bar module is special and injects it's controller into the middle view so it can share data with it's special bar header.
    middle: { template: 'middle.html', controller: 'BarCtrl as bar' },
    header: { template: 'bar-header.html' },
    main: { template: 'bar.html' },
  },
})
<!-- middle.html -->
<header jem-view=header>
<div jem-view=main>
<!-- header.html -->
<nav>
  <a href=/foo>foo</a>
  <a href=/bar>bar</a>
  breadcrumbs or something
</nav>
<!-- foo.html -->
Welcome to foo
<!-- bar-header.html -->
There are {{bar.count}} bar
<button ng-click="bar.create()">+ New<button>
<!-- bar.html -->
Welcome to bar
  1. When transitioning from top.foo to top.bar there is an old jem-view=middle and a new jem-view=middle, each contain a jem-view=main.
  2. The old jem-view=main observes a view event and it's update() requests the template. At this point the jem-view is still a descendant of the root element and its scope is still valid.
  3. The old jem-view=middle scope is destroyed and detached from it's parent.
  4. The old jem-view=main proceeds to compile and link the template contents against a new child scope.

Directives in the template will not see a $destroy event (it already fired), and can therefore leak resources.

jeme commented 9 years ago

I'll work on getting a working demonstration and/or test case.

If you could manage to get that into a plunker that would be great so I can dig into it.

The fix as done here smells like treating a symptom rather than the root cause, and obviously we would like to fix the root cause instead. We might have to live with that until the root cause can be identified though...

groner commented 9 years ago

@jeme I assume you're still interested in seeing a plunk?

I wasn't able to create a plunk showing the issue. I can try using our application and taking away pieces until I've isolated the issue.

jeme commented 9 years ago

Yes I would still be interested in a plunk to identify the root cause.