EasyCo
EasyCo

Reputation: 2036

EmberJS nesting

Given the following code, I thought the person.index and nested person.finish routes would use the PersonController content/model property since theirs was empty/undefined? What am I doing wrong? http://jsfiddle.net/EasyCo/MMfSf/5/

To be more concise: When you click on the id, the {{id}} and {{name}} are blank? How do I fix that?

Functionality

// Create Ember App
App = Ember.Application.create();

// Create Ember Data Store
App.Store = DS.Store.extend({
    revision: 11,
    adapter: 'DS.FixtureAdapter'
});

// Create parent model with hasMany relationship
App.Person = DS.Model.extend({
    name: DS.attr( 'string' ),
    belts: DS.hasMany( 'App.Belt' )

});

// Create child model with belongsTo relationship
App.Belt = DS.Model.extend({
    type: DS.attr( 'string' ),
    parent: DS.belongsTo( 'App.Person' )
});

// Add Person fixtures
App.Person.FIXTURES = [{
    "id" : 1,
    "name" : "Trevor",
    "belts" : [1, 2, 3]
}];

// Add Belt fixtures
App.Belt.FIXTURES = [{
    "id" : 1,
    "type" : "leather"
}, {
    "id" : 2,
    "type" : "rock"
}, {
    "id" : 3,
    "type" : "party-time"
}];


App.Router.map( function() {
    this.resource( 'person', { path: '/:person_id' }, function() {
        this.route( 'finish' );
    });
});

// Set route behaviour
App.IndexRoute = Ember.Route.extend({
  model: function() {
    return App.Person.find();
  },
  renderTemplate: function() {
    this.render('people');
  }
});

Templates

<script type="text/x-handlebars">
    <h1>Application</h1>
    {{outlet}}
</script>

<script type="text/x-handlebars" id="people">
    <h2>People</h2>
    <ul>
    {{#each controller}}
        <li>
            <div class="debug">
                Is the person record dirty: {{this.isDirty}}
            </div>
         </li>
        <li>Id: {{#linkTo person this}}{{id}}{{/linkTo}}</li>
        <li>Name: {{name}}</li>
        <li>Belt types:
            <ul>
            {{#each belts}}
                <li>{{type}}</li>
            {{/each}}
            </ul>
        </li>
    {{/each}}
    </ul>
</script>

<script type="text/x-handlebars" id="person">
    <h2>Person</h2>
    Id from within person template: {{id}}<br><br>
    {{outlet}}
</script>

<script type="text/x-handlebars" id="person/index">
    Id: {{id}}<br>
    Name: <a href="#" {{action  "changeName"}}>{{name}}</a><br><br>

    {{#linkTo index}}Go back{{/linkTo}}<br>
    {{#linkTo person.finish}}Go to finish{{/linkTo}}
</script>



<script type="text/x-handlebars" id="person/finish">
    <h2>Finish</h2>
    {{id}}
</script>

Upvotes: 1

Views: 545

Answers (2)

xamenrax
xamenrax

Reputation: 1744

You can use this in your router:

  model: function() {
    return this.modelFor("person");
  }

Instead of your's:

controller.set('content', this.controllerFor('person'));

Upvotes: 1

ken
ken

Reputation: 3745

Your views were served through different controllers, either Ember's generated one or the one you defined PersonIndexController and that contributed to the issue you were facing. Instead of patching your original example to make it work, i instead reworked it to show you how you should structure your views/routes to leverage Emberjs capabilities.

You should design your application/example as a series of states working and communicating with each other and captured in a Router map. In your example, you should have a people, person resource and a finish route with corresponding views and controllers, either you explicitly create them or let Ember do that for you, providing you're following its convention.

Here's a working exemple and below I highlighted some of the most important parts of the example

<script type="text/x-handlebars" data-template-name="people">
    <h2>People</h2>
    <ul>
    {{#each  person in controller}}
        <li>
            <div class="debug">
                Is the person record dirty: {{this.isDirty}}
            </div>
         </li>
        <li>Id: {{#linkTo 'person' person}}{{person.id}}{{/linkTo}}</li>
        <li>Name: {{person.name}}</li>
        <li>Belt types:
            <ul>
            {{#each person.belts}}
                <li>{{type}}</li>
            {{/each}}
            </ul>
        </li>
    {{/each}}
    </ul>
</script>

<script type="text/x-handlebars" data-template-name="person">
    <h2>Person</h2>
    Id from within person template: {{id}}<br><br>
    Id: {{id}}<br>
    Name: <a href="#" {{action  "changeName"}}>{{name}}</a><br><br>

    {{#linkTo index}}Go back{{/linkTo}}<br>
    {{#linkTo person.finish}}Go to finish{{/linkTo}}
    {{outlet}}
</script>

Models, Views, Controllers and Route definitions

DS.RESTAdapter.configure("plurals", { person: "people" });

App.Router.map( function() {
    this.resource('people',function() {
        this.resource('person', { path: ':person_id' }, function() {
            this.route( 'finish');
        });    
    })

});

App.PeopleController = Ember.ArrayController.extend();
App.PeopleRoute = Ember.Route.extend({
    model: function() {
        return App.Person.find();
    }
})

App.IndexRoute = Ember.Route.extend({
    redirect: function() {
        this.transitionTo('people');
    }
});
App.PersonRoute = Ember.Route.extend({
    model: function(params) {
        debugger;
        return App.Person.find(params.client_id);
    },
    renderTemplate: function() {
        this.render('person',{
            into:'application'
        })
    }
})

App.PersonFinishRoute = Ember.Route.extend({
    renderTemplate: function() {
        this.render('finish',{
            into:'application'
        })
    }
})

Upvotes: 1

Related Questions