Understanding Ember Routes and Models

52 Views Asked by At

I try to understand how Ember works and I have an issue I can't understand. I am following a tutorial (guides.emberjs.com/v1.10.0/) and I don't understand why I only see an element when I go on a page when I click (and doesn't work with a direct link).

I think some screenshots will be helpful to understand my issue.

This is what I have when I visit "index.html#/posts/1". No article is displayed.

https://i.stack.imgur.com/qzwlq.png

This is what I have when I visit "index.html#/posts" and then click on Rails is Omakase on the left. An article is displayed whereas the link is on my browser is "index.html#/posts/1" (and when I refresh nothing is displayed).

https://i.stack.imgur.com/YpmzX.png

This is my index.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Blog tuto</title>
  <link rel="stylesheet" href="css/normalize.css">
  <link rel="stylesheet" href="css/style.css">
  <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css">
</head>
<body>
  <script type="text/x-handlebars">
    <div class="navbar">
      <div class="navbar-inner">
        <a class="brand" href="#">Bloggr</a>
        <ul class="nav">
          <li>{{#link-to "posts.index"}}Posts{{/link-to}}</li>
          <li>{{#link-to "about"}}About{{/link-to}}</li>
        </ul>
      </div>
    </div>
    {{outlet}}
  </script>

  <script type="text/x-handlebars" id="about">
    <p>
      Lorem ipsum about
    </p>
  </script>

  <script type="text/x-handlebars" id="posts">
    <div class="container-fluid">
      <div class="row-fluid">
        <div class="span4">
          <table class="table">
            <thead>
              <tr><th>Recent Posts</th></tr>
            </thead>
            {{#each post in model}}
            <tr>
              {{#link-to "posts.post" post}}
              <td>{{post.title}} <small class="muted">by {{post.author}}</small></td>
              {{/link-to}}
            </tr>
            {{/each}}
          </table>
        </div>
        <div class="span8">
          {{outlet}}
        </div>
      </div>
    </div>
  </script>

  <script type="text/x-handlebars" id="posts/post">
    {{#if isEditing}}
      {{partial "post/edit"}}
      <button {{action "doneEditing"}}>Done</button>
    {{else}}
      <button {{action "edit"}}>Edit</button>
    {{/if}}
    <h1>{{title}}</h1>
    <h2><small class="muted">by {{author}}</small></h2>
    <hr>
    <div class="intro">
      {{exerpt}}
    </div>
    <div class="below-the-fold">
      {{body}}
    </div>
  </script>

  <script type="text/x-handlebars" id="post/edit">
    <p>{{input type="text" value=title}}</p>
    <p>{{input type="text" value=exerpt}}</p>
    <p>{{textarea value=body}}</p>
  </script>

  <script src="../js/libs/jquery.min.js"></script>
  <script src="../js/libs/handlebars.js"></script>
  <script src="../js/libs/ember.js"></script>
  <script src="../js/libs/ember-data.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.1.0/moment.min.js"></script>

  <script src="app.js"></script>
</body>
</html>

And app.js

App = Ember.Application.create();

App.Router.map(function() {
    this.route('about');
    this.resource('posts', function () {
        this.route('post', {path: ':post_id'});
    });

});

App.PostsRoute = Ember.Route.extend({
    model: function () {
        return posts;
    }
});

App.PostsPostRoute = Ember.Route.extend({
    model: function (params) {
        return posts.findBy('id', params.post_id);
    }
});

App.PostsPostController = Ember.ObjectController.extend({
    isEditing: false,

    actions: {
        edit: function () {
            this.set('isEditing', true);
        },
        doneEditing: function () {
            this.set('isEditing', false);
        }
    }
});


var posts = [{
    id: 1,
    title: "Rails is Omakase",
    author: "mc100s",
    date: new Date('08-06-2015'),
    exerpt: "Lorem ipsum dolor sit amet",
    body: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
}, {
    id: 2,
    title: "The Parley Letter",
    author: "mc100s",
    date: new Date('08-06-2015'),
    exerpt: "Duis aute irure dolor in reprehenderit",
    body: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
}];

Thank you for your help

1

There are 1 best solutions below

6
On BEST ANSWER

When you click link, model is passed directly to the route and route's model hook is not fired, so you see article. When you reload route model hook is fired and something goes wrong.

Make string id, because params.post_id is String.

findBy is Ember.Array method. http://emberjs.com/api/classes/Ember.Array.html#method_findBy I would try:

var posts = Ember.A([{
  // as is
}]); 

Next change ObjectController to Controller (ObjectController is deprecated) and use {{model.title}} instead of {{title}} in template:

<script type="text/x-handlebars" id="posts/post">
  {{#if isEditing}}
    {{partial "post/edit"}}
    <button {{action "doneEditing"}}>Done</button>
  {{else}}
    <button {{action "edit"}}>Edit</button>
  {{/if}}
  <h1>{{model.title}}</h1>
  <h2><small class="muted">by {{model.author}}</small></h2>
  <hr>
  <div class="intro">
    {{model.exerpt}}
  </div>
  <div class="below-the-fold">
    {{model.body}}
  </div>

working jsbin here: http://jsbin.com/pozabixeka/edit?html,js,output