最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Ember.js Routercontroller properties - Stack Overflow

programmeradmin2浏览0评论

I'm trying to wrap my head around the model property or a route vs. the content property of the controller. If you set the model property in a route, does this automatically set it to the content property in a generated controller.

Also, I think the content property of the controller allows you to access the attributes of that object in the template, is that true?

I read the docs and still am having trouble digesting some of these conventions.

I'm trying to wrap my head around the model property or a route vs. the content property of the controller. If you set the model property in a route, does this automatically set it to the content property in a generated controller.

Also, I think the content property of the controller allows you to access the attributes of that object in the template, is that true?

I read the docs and still am having trouble digesting some of these conventions.

Share Improve this question edited Apr 9, 2013 at 14:45 MilkyWayJoe 9,0922 gold badges40 silver badges53 bronze badges asked Apr 9, 2013 at 13:28 brandonhilkertbrandonhilkert 4,4857 gold badges26 silver badges39 bronze badges 2
  • 2 Have you seen any of the introduction screencasts that show how to use routes/views/controllers/models? I did one a month ago that covers the basics in 36 minutes toranbillups./blog/archive/2013/03/02/… – Toran Billups Commented Apr 9, 2013 at 13:43
  • I haven't seen that one. I watched this one (youtube./watch?v=7O9X5oeAJm4) and it really helped me understand the overall structure of things. I'll check this one out. Thanks! – brandonhilkert Commented Apr 9, 2013 at 14:05
Add a ment  | 

1 Answer 1

Reset to default 7

As answered here, Ember.Route has a model function which allows you to set an object or a collection of objects as the model of that route. Routes that deal with a single object should have a controller that extends Ember.ObjectController while routes that deal with a collection of objects should have a controller that extends Ember.ArrayController. Subsequently, in the Route workflow, the data ing from the model hook is set into the controller's content property via setupController hook.

The routes have their own workflow to setup their controllers, so by default this method will be called and populate the content with the model. Consider the following:

fiddle

App.Email = DS.Model.extend({
    address: DS.attr('string'),
    isActive: DS.attr('boolean')
});

App.Router.map(function() {
    this.resource('emails', function() {
        this.route('email', {path: ':email_id'});
    });
});

App.EmailsRoute = Ember.Route.extend({
    model: function() {
        return App.Email.find();
    }
});
App.EmailRoute = Ember.Route.extend({
    model: function(params) {
        return App.Email.find(params.email_id);
    }
});

App.EmailsController = Ember.ArrayController.extend();
App.EmailController = Ember.ObjectController.extend();

The framework should generate the default code for these routes in order to setup the controller, which would look like this (and you can override if you want):

App.EmailsRoute = Ember.Route.extend({
    ...
    setupController: function(controller, model) {
        controller.set('content', model);
    }
    ...
});

There are cases (see question/answer linked above) in which you may need/want to override these methods to do something different than the default functionality, for example:

fiddle

App.EmailsRoute = Ember.Route.extend({
    model: function(params) {
        return [{id: 1, address: '[email protected]'}];
    },
    setupController: function(controller, model) {
        // here, controller is whatever controller this route needs
        // by conventions, it knows it should be EmailsController
        // of the type ArrayController
        // model is whatever was returned by the model function above

        // the content is a "bag" which can be filled with a model or any
        // other object you need. Just keep in mind your view layer will
        // be referring to this object later on
        controller.set('content', model);

        // you can set other properties of the controller here too
        controller.set('applyFilter', true);
    }
});

Now the templates will be able to access the data in the controller. The example below iterates through a collection of objects (App.Email) in the EmailsController. Any public attribute in this collection or in its child objects are accessible here, one example is {{email.address}}:

<script type="text/x-handlebars" data-template-name="emails">
    <ul>
    {{#each email in controller}}
        <li>
            {{#linkTo emails.email email}}
                {{email.address}}
            {{/linkTo}}
        </li>    
    {{/each}}
    </ul>
    {{outlet}}
</script>

Note that the template is not talking directly to the model, but rather to the content, which was assigned with data from the model. Like I said, you can stash any object in the content or model via routes, so you're not tied to use DS.Model nor the architecture is strongly coupled.

If this model, instead of App.Email type, had a different type with different attributes, it would also be accessible here, with limitations tho. If an attribute of the model is a collection, it cannot be accessed through index (e.g. {{email.messages[0].body}} wouldn't work). The best course of action in this case, would be a puted property in the controller which would give you direct access to the first item of the messages collection of the email, if it had one.

发布评论

评论列表(0)

  1. 暂无评论