简体   繁体   English

Ember.js路由器/控制器属性

[英]Ember.js Router/controller properties

I'm trying to wrap my head around the model property or a route vs. the content property of the controller. 我想把头放在控制器的model属性或路由与content属性之间。 If you set the model property in a route, does this automatically set it to the content property in a generated controller. 如果在路径中设置model属性,它会自动将其设置为生成的控制器中的content属性。

Also, I think the content property of the controller allows you to access the attributes of that object in the template, is that true? 另外,我认为控制器的content属性允许您访问模板中该对象的属性,是真的吗?

I read the docs and still am having trouble digesting some of these conventions. 我阅读了文档,但仍然难以消化其中的一些约定。

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. 作为回答这里Ember.Route有一个model功能,允许您设置一个或多个对象作为此路线的模型的集合。 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 . 处理单个对象的路由应该有一个扩展Ember.ObjectController的控制器,而处理对象集合的路由应该有一个扩展Ember.ArrayController的控制器。 Subsequently, in the Route workflow, the data coming from the model hook is set into the controller's content property via setupController hook. 随后,在Route工作流程中,来自model挂钩的数据通过setupController挂钩设置为控制器的content属性。

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: 'other@email.com'}];
    },
    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 . 通过对象的集合(下面迭代的例子App.Email在) EmailsController Any public attribute in this collection or in its child objects are accessible here, one example is {{email.address}} : 此处可以访问此集合或其子对象中的任何公共属性,例如{{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. 请注意,模板不直接与模型对话,而是与content对话, content是使用模型中的数据分配的。 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. 就像我说的那样,您可以通过路由将任何对象DS.Model在内容或模型中,因此您不必使用DS.Model也不DS.Model体系结构紧密耦合在一起。

If this model, instead of App.Email type, had a different type with different attributes, it would also be accessible here, with limitations tho. 如果此模型(而不是App.Email类型)具有具有不同属性的其他类型,则也可以在此受限制地访问它。 If an attribute of the model is a collection, it cannot be accessed through index (eg {{email.messages[0].body}} wouldn't work). 如果模型的属性是集合,则无法通过索引访问它(例如{{email.messages[0].body}}无效)。 The best course of action in this case, would be a computed 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. 在这种情况下,最好的做法是在控制器中使用计算属性,如果有的话,您可以直接访问电子邮件的消息集合的第一项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM