haxxxton haxxxton - 3 months ago 28
AngularJS Question

Angular UI Router root named view template change from child view

Setup is using Angular v1.5.8, and ui-router v0.3.1 . My root view has several named sections (ive removed a number of them for brevity). It looks like this

<section id="container">
<div id="main">
<div id="overlay">
<section id="overlay__content" ui-view="overlay"></section>
</div>
<div id="content">
<section id="content__content" ui-view="content"></section>
</div>
</div>
</section>


My state controller looks like this

$stateProvider
.state('app',{
url: '/',
abstract: true,
views: {
'overlay': {
templateUrl: partialsUrl + 'main.overlay.html', // <-- content below
controller: 'OverlayController',
controllerAs: 'vm'
}
}
})
.state('app.foo', {
url: 'foo',
views: {
'content@': {
templateUrl: partialsUrl + 'foo.main.html',
controller: 'FooController',
controllerAs: 'vm'
}
}
})
.state('app.foo.add', {
url: '/add',
views:{
'content@overlay':{ // <-- DOES NOT WORK
templateUrl: partialsUrl + 'foo.add.html',
controller: 'FooAddController',
controllerAs: 'vm'
}
}
})


My overlay view template (
main.overlay.html
) looks like this

<a class="close">&times;</a>
<div ui-view="content"></div> <!-- <-- LOAD CONTENT INTO HERE -->


What Im trying to do is when the
app.foo.add
state is initiated to load content into the
content
section of the
overlay
root named view. I can access the root content view using
content@
successfully as described here. However, there doesnt seem to be any documentation about traversing into a states's view deeply. Ideally i would imagine i would want something like
content@app(overview)
(assuming that
()
allowed you to select a named view and then go into it, or perhaps
content@app@overview
. Neither of which work.

Any suggestions for a solution or something fundamental that im missing would be greatly appreciated

Answer

If I've interpreted your problem correctly, then I think this should work:

<!doctype html>
<html>
  <head>
    <script src="bower_components/angular/angular.js"></script>
    <script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
    <script>
      angular.module('app', ['ui.router']).config(function($stateProvider){
        $stateProvider
          .state('app', {
            url: '/',
            abstract: true,
            views: {
              'overlay': {
                templateUrl: 'overlay.html'
              }
            }
          })
          .state('app.foo', {
            url: 'foo',
            views: {
              'content@': {
                templateUrl: 'foo.content.html'
              }
            }
          })
          .state('app.foo.add', {
            url: '/add',
            views: {
              'content@app': {
                templateUrl: 'foo.add.content.html'
              }
            }
          });
      }).run(function($state){
        $state.go('app.foo.add');
      });
    </script>
  </head>
  <body ng-app="app">
    <div ui-view="overlay">

    </div>
    <div ui-view="content">

    </div>
    <script type="text/ng-template" id="overlay.html">
      <h1>Overlay</h1>
      <div ui-view="content"></div>
    </script>
    <script type="text/ng-template" id="foo.content.html">
      <h1>Foo Content</h1>
    </script>
    <script type="text/ng-template" id="foo.add.content.html">
      <h1>Foo Add Content</h1>
    </script>
  </body>
</html>

Explanation

I think the misunderstanding you have is what the symbol after the @ stands for. The symbol before the @ is the name of the view you want to match, and the symbol after the @ is a reference to the state in which the template the ui-view directive should exist in.

So in this example, content@app is saying look for ui-view="content" inside any of the views inside the app state.

Hopefully that made sense.