2

I'm using UI-Router to build an application. I need to have multiple views on one page so I'm using abstract states. I tried to pass the parameter "isEmbedded" to the owner view, but it's unfortunately not working. I'm wondering if its because I'm passing it to a child view. When I console.log($stateParams) in ownerCtrl, it does not show the isEmbedded parameter. Any idea why?

.state('dog', {
    url: "",
    parent: "dogAbstract",
    views: {
        "owner": {
            templateUrl: 'client/people/views/owner.ng.html',
            controller: 'ownerCtrl',
            params:{
                isEmbedded:true
            }
        }
    }
})

P.S. I got the idea to use params from this question:

Angular ui router passing data between states without URL

Community
  • 1
  • 1
user3413723
  • 11,147
  • 6
  • 55
  • 64
  • The `stateParams` belongs to state, not to view. Why you need to have params `isEmbedded`? What purpose that should serve to? – Radim Köhler Dec 22 '15 at 18:15
  • I need to render the owner view slightly differently if it is embedded. I render owner view on its own sometimes, and at other times I render it within another view, and I need to know which it is in in order to make required changes. – user3413723 Dec 22 '15 at 18:20
  • I would say, that the best is to use `resolve`. I created an example to demonstrate that. The advantage is, that it could be view (not just state) related – Radim Köhler Dec 22 '15 at 18:25

1 Answers1

2

While $stateParams belongs to state, we can use special resolve for a view:

...
views: {
    "owner": {
        templateUrl: 'client/people/views/owner.ng.html',
        controller: 'ownerCtrl',
        resolve:{
            isEmbedded: function() { return true},
        }
    }
}

I created an example here with these two child states

.state('parent.child', { 
      url: "/child",
      templateUrl: 'tpl.html',
      controller: 'ChildCtrl',
      resolve: {
        isEmbedded: function() { return false},
      }
})
.state('parent.child2', { 
      url: "/child2",
      templateUrl: 'tpl.html',
      controller: 'ChildCtrl',
      resolve: {
        isEmbedded: function() { return true},
      }
})

And controller can consume it:

.controller('ChildCtrl', ['$scope', 'isEmbedded', 
  function ($scope, isEmbedded) { 
    console.log(isEmbedded)
  }
])

Check it here

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Sweet! A bit of a workaround, but it is probably the best way given the current state of ui-router. Probably would have taken me a couple days to learn enough about ui-router to come up with this on my own. Thanks you! – user3413723 Dec 22 '15 at 19:00
  • Great to see that. Enjoy UI-Router ;) – Radim Köhler Dec 22 '15 at 19:01
  • Hi Radim, I've run into a problem. If I don't write the `resolve` code on every state that contains `owner` I get `Unknown provider isEmbedded` error. Any way to solve this without writing the `resolve` on every state that contains owner? – user3413723 Dec 22 '15 at 20:03
  • Yes. There is - see this updated plunker http://plnkr.co/edit/qjinnTwIuQk4Zi7jA9nm?p=preview. The point is - move the default setting to the root state of the state hierarchy. Each state will/could be by default be provided with default setting ... but ones you want could override that. I for example have one state "app" on top of all, exactly for such kind of reason... enjoy this mighty extension - UI-Router ;) – Radim Köhler Dec 23 '15 at 04:18