2

So, it seems I am not getting ui-router, after all.

Here is the broken example: http://plnkr.co/edit/WgDqTzE3TJjrCZ2pxg5T?p=preview

The actual file structure is:

app/
  app.js
  index.html
  main/
    main.html
    header/
      header.html
    footer/
      footer.html
    sections/
      content1/
        content1.html
      content2/
      ...

index.html has a simple <div ui-view></div>

main.html has:

    <div ui-view="header"></div>
    <div ui-view></div>
    <div ui-view="footer"></div>

header.html, footer.html, content1.html, ... have actual content.

app.js has:

$stateProvider
  .state("app", {
    url: "",
    abstarct: true,
    templateUrl: "main.html"
  })

  .state("app.main", {
    url: "",
    abstarct: true,
    views: {
      "header": {
        templateUrl: "header.html"
      },
      "footer":{
        templateUrl: "footer.html"
      }
    }
  })

  .state("app.main.content1", {
    url: "/",
    templateUrl: "content1.html"
  });

So, I thought this meant going to "/" would show me header, footer, and automatically insert content in the unnamed ui-view.

It does not. What am I doing wrong?

fusio
  • 3,595
  • 6
  • 33
  • 47

1 Answers1

1

To make it quickly working (not as intended) I've just added an anchor into the footer and now it is working

<div>
  im footer
  <div ui-view=""></div>
</div>

Why? because our state def is like this:

.state("app.main.content1", {
    url: "/",
    templateUrl: "content1.html"
  });

Which means:

do search for unnamed view in my parent

The footer view is a parent of the state "app.main.content1", so this way we can target it.

There are other options as well.

Here is what was most likely intended: , state defintion is changed:

.state("app.main.content1", {
  url: "/",
  views: {
    "@app": {
      templateUrl: "content1.html"
    }
  }

So, now we target the app state, its view anchor <div ui-view="">, by the absolute naming. See:

Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname@statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.

At the end, we can reach the same with even one abstract state and one child, check it here:

$stateProvider
 .state("app", {
  url: "",
  abstarct: true,
  views: {
    "" : {
      templateUrl: "main.html",
    },
    "header@app": {
      templateUrl: "header.html"
    },
    "footer@app":{
      templateUrl: "footer.html"
    }
  }
})  

.state("app.content1", {
  url: "/",
  templateUrl: "content1.html",
});

Now, the all UI-Router magic is happening in the root state def. We firstly target root (index.html) unnmaed view, to inject the main.html. Next - othe views target this state itself (the main.html) via "header@app" - absolute naming

That would be the most suitable way... working example

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • This is great, I needed to target `@app`! Just two clarifications: Why is the footer view parent of the content view in the first example? Is there a better way to do something similar to what I am doing right now? (`app` and `app.main` states seem almost redundant) – fusio Oct 03 '14 at 12:22
  • I would say *(just my point of view)* two abstract parents is too much. We can solve it with only one parent. See my updated answer – Radim Köhler Oct 03 '14 at 12:27
  • Great if that helped anyhow. Enjoy amazing `UI-Router` ;) – Radim Köhler Oct 03 '14 at 12:30
  • if it is not too much, can I bother you with [another question](http://stackoverflow.com/questions/26216661/)? :) @Radim – fusio Oct 06 '14 at 15:21
  • 1
    @fusio - If I will know, more than ready to assist... And I checked that there is already answer... by chris (developer of UI-Router) ... so it should be what you need... please, if that does not work for you... let me know. Not sure if I can help, but will try... – Radim Köhler Oct 06 '14 at 15:58