tspore
tspore

Reputation: 1349

Ember local Variables in views

So in Ember if I have a model called "foos" - it will load a template with the data-template-name="foos", however I am not sure how to wipe "foos" from the screen when I load 1 "foo" as well as I am not sure how to can the instance variable in the controller such as @foos to do a @foos.length. for some other stuff I want to do. Currently my view doesn't load if I call foos.isLoaded as well as if I call foo #4 It will appendTo the page the view. but not redraw the view.

I just don't know how to figure out what the default stuff looks like I guess.

My controller stuff- Router

App.Router.map(function(){
    this.resource('records', function(){
        this.resource('record', {path: ':record_id'});
    });
});

App.FoosRoute = Ember.Route.extend({
    model: function() {
        return App.Foo.find();
    }
});

// Controller
App.FoosController = Ember.ArrayController.extend({
    itemController: 'record'
});

App.FooController = Ember.ObjectController.extend({
    fullName: function() {
        return this.get('firstName') + ' ' + this.get('middleName') + ' ' + this.get('surname') + ' ' + this.get('suffix')
    }.property('firstName', 'middleName', 'surname', 'suffix')
})

// Model
App.Store = DS.Store.extend({
    revision: 11,
    adapter: 'DS.RESTAdapter'
});


App.Foo = DS.Model.extend({
    firstName: DS.attr('string'),
    middleName: DS.attr('string')
     .....
})

My views:

<script type="text/x-handlebars" data-template-name="application">
  {{ outlet }}
</script>


<script type="text/x-handlebars" data-template-name="foos">
  <div class="one_half">
    <h2>Search</h2>
    form here....
  </div>
  <div class="one_half">
    <div id="smallMap">
      map
    </div>
  </div>
  <div id="foos">

    <table>
      <tr>
        <th>Name</th>
        <th>Birth</th>
        <th>Death</th>
      </tr>

      {{#each foo in controller}}
      {{#if foo.isLoaded}}
      <tr>
        <td>{{#linkTo "foo" foo}} {{foo.fullName}} {{/linkTo}}</td>
        <td>{{#linkTo "foo" foo}} {{foo.birthMonth}} {{#if foo.birthMonth}}/{{/if}}{{foo.birthDay}} {{#if foo.birthDay}}/{{/if}}{{foo.birthYear}} {{/linkTo}}</td>
        <td>{{#linkTo "foo" foo}}{{foo.deathMonth}}{{#if foo.deathMonth}}/{{/if}}{{foo.deathDay}}{{#if foo.deathDay}}/{{/if}}{{foo.deathYear}}{{/linkTo}} {{foo.trAlt}}</td>
      </tr>
      {{else}}
      <tr>
        <td colspan="3"  class="loading">Records are loading</td>
      </tr>
      {{/if}}
      {{/each}}
    </table>

  </div>

  {{outlet}}
</script>

<script type="text/x-handlebars" data-template-name="foo">
  <h3>A Record</h3>
  {{id}}
  {{firstName}}
</script>

Currently it doesn't kill the view and bring in the new ones.

Upvotes: 0

Views: 473

Answers (1)

Mike Grassotti
Mike Grassotti

Reputation: 19050

Hmmm - there is a lot going on here, going to try and point you in the right direction.

So in Ember if I have a model called "foos" - it will load a template with the data-template-name="foos"

Not exactly. Convention is to use the same name, but the ember does not load a template based on the model. If anything it's the other way around. Your best bet is usually to start with templates then work your way backwards to the model layer. So in this case let's start with 3 templates - application, foo and foos:

<script type="text/x-handlebars" data-template-name="application">
  <h1>Foo App</h1>
  {{outlet}}
</script>

<script type="text/x-handlebars" data-template-name="foos">
  <h3>All Foos:</h3>
  <ul>
  {{#each controller}}<li>{{fullName}}</li>{{/each}}
  </ul>
</script>

<script type="text/x-handlebars" data-template-name="foo">
  <h3>Foo Details:</h3>
  <p>{{fullName}}</p>
</script>

however I am not sure how to wipe "foos" from the screen when I load 1 "foo"

Ember will take care of rendering the appropriate view when the route changes. One way to make this possible is by adding links to your application. For example, modify foos template so that each record is a link, and add a Show All link to the detail page.

<script type="text/x-handlebars" data-template-name="foos">
  <h3>All Foos:</h3>
  <ul>
  {{#each controller}}
   <li>{{#linkTo "foo" this}}{{fullName}}{{/linkTo}}</li>
  {{/each}}
  </ul>
</script>

<script type="text/x-handlebars" data-template-name="foo">
  <h3>Foo Details:</h3>
  <p>{{fullName}}</p>
  <p>{{#linkTo foos}}Show all{{/linkTo}}</p>
</script>

as well as I am not sure how to can the instance variable in the controller such as @foos to do a @foos.length for some other stuff I want to do

Not sure what your getting at. @foos is not an instance variable, unless you are using coffeescript and really mean this.foos.

Currently my view doesn't load if I call foos.isLoaded as well as if I call foo #4 It will appendTo the page the view. but not redraw the view.

Right. Calling foos.isLoaded just tells you if the model is loaded, it has nothing to do with the view. What do you mean call foo #4? Seems there might be code you are referencing that didn't get included in your SO post.

I just don't know how to figure out what the default stuff looks like I guess.

OK. I've made some guesses about what you're trying to do and created a working example. Code below, or see this working example on jsbin

First, I've added an application definition. Then changed your routes to be foos instead of records. Also no need for a nested route in this case.

App = Em.Application.create({});

App.Router.map(function(){
  this.route('foos', {path: '/'});
  this.resource('foo',{path: '/foos/:foo_id'});
});

FooRoute, FoosController and FooController were ok as-is.

App.FoosRoute = Ember.Route.extend({
    model: function() {
        return App.Foo.find();
    }
});

// Controller
App.FoosController = Ember.ArrayController.extend({
    itemController: 'foo'
});

App.FooController = Ember.ObjectController.extend({
    fullName: function() {
        return this.get('firstName') + ' ' + this.get('middleName') + ' ' + this.get('surname') + ' ' + this.get('suffix');
    }.property('firstName', 'middleName', 'surname', 'suffix')
});

Added missing properties to App.Foo

App.Foo = DS.Model.extend({
    firstName: DS.attr('string'),
    middleName: DS.attr('string'),
    surname: DS.attr('string'),
    suffix: DS.attr('string')
});

Switching to DS.FixtureAdapter and added 4 fixture records to simulate what might be returned by your API

App.Store = DS.Store.extend({
  revision: 11,
  adapter: DS.FixtureAdapter
});

App.Foo.FIXTURES = [
  {id: 1, firstName: 'Michael', middleName: 'Paul'},
  {id: 2, firstName: 'Jennifer', middleName: 'Lyn'},
  {id: 3, firstName: 'Sophia', middleName: 'Marie'},
  {id: 4, firstName: 'Greta', middleName: 'Fae'}
];

Upvotes: 2

Related Questions