Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UI Router: Multiple Independent Views

I feel like this is a straight forward use case for the ui-router but maybe I'm missing something...

I want to have two separate views next to each other controlled by their own menus. When I click a ui-sref link on one menu (or $state.go for that matter), I would like to update only one of the views. Additionally, only one of the two views needs to be reflected in the url.

I tried defining a few states:

$stateProvider
.state('home', {
  url: '/',
  views: {
    'viewA': {
      template: "I'm number A!"
    },
    'viewB': {
      template: "It's good to be B."
    }
  }
})
.state('shouldOnlyChangeA', {
  'url': '',
  views: {
    'viewA': {
       template: 'Check out my new shoes!'
     }
  }
})
.state('shouldOnlyChangeB', {
  'url': '/shouldGoToNewUrl',
  views: {
    'viewB': {
       template: "This probably won't work..."
     }
  }
});

Now press $state.go('shouldOnlyChangeA') from your favorite controller and watch it change the crap out of viewB. I'd also like to omit the url definition in this state since the url should only change between the first and third states I've defined.

I have each ui-view sitting next to each other in index.html:

...
<div ui-view="viewA"></div>
<div ui-view="viewB"></div>
...

TL;DR

I want two sibling ui-views to be stateful all on their own; changing one shouldn't necessarily effect the other.

Hopefully I'm just missing something so I didn't bother to throw a plunker together or anything, but if it's more complicated and folks are willing to fiddle I'll whip something up.

like image 243
cazzer Avatar asked Sep 30 '14 06:09

cazzer


1 Answers

See this similar question: Independent routing for multiple regions in an AngularJS single page application


I wrote UI-Router Extras - sticky states to accomplish this use case.

View the demo Check out the demo source code for details.

I wrote UI-Router Extras - sticky states to achieve your goal.

You'll want one named <div ui-view='name'></div> for each region. Then, add sticky: true to the state definition which targets that region's named view.

See this plunk: http://plnkr.co/edit/nc5ebdDonDfxc1PjwEHp?p=preview

<div ui-view="viewA"></div>
<div ui-view="viewB"></div>

...

$stateProvider
.state('home', {
  url: '/'
 })
.state('shouldOnlyChangeA', {
  'url': '',
  sticky: true, // Root of independent state tree marked 'sticky'
  views: {
    'viewA@': {
       template: 'Check out my new shoes!<div ui-view></div>'
     }
  }
})
.state('shouldOnlyChangeA.substate', {
  'url': '/substate',
  template: 'Lets get some shoes!'
})
.state('shouldOnlyChangeB', {
  'url': '/shouldGoToNewUrl',
  sticky: true,  // Root of independent state tree marked 'sticky'
  views: {
    'viewB': {
       template: "This probably won't work...<div ui-view></div>"
     }
  }
})
.state('shouldOnlyChangeB.substate', {
  'url': '/substate',
  template: "Golly, it worked"
  }
);
like image 93
Chris T Avatar answered Oct 16 '22 04:10

Chris T