Ember JS -在用belongsTo关系加载多个模型到一个路由时遇到问题

Ember JS - Having trouble loading multiple models into a route with belongsTo relationship

本文关键字:一个 路由 问题 遇到 模型 在用 JS belongsTo 关系 加载 Ember      更新时间:2023-09-26

我被困在这种情况下,我不能正确设置我的数据。我希望能够加载我所有的帖子,并有作者数据加载与每个帖子以及。这些是我的模型。

App.Post = DS.Model.extend({
    authorId:   DS.attr('number'),
    author:     DS.belongsTo('author'),
    title:      DS.attr('string'),
    body:       DS.attr('string'),
    snippet:    DS.attr('string'),
    postDate:   DS.attr('date'),
    imageName:  DS.attr('string'),
    postSnippit: Ember.computed();
    imageUrl: Ember.computed()})
});

App.Author = DS.Model.extend({
    name:        DS.attr('string'),
    imageName:   DS.attr('string'),
    posts:       DS.hasMany('post')
});

,这是我的路由器的相关部分…

App.Router.map(function() {
    this.route('blog', {path: '/blog'}, function() {
        this.resource('posts', { path: '/' });
        this.resource('post', {path: '/:id'});
    });
});

我已经正确设置了一个单一的帖子,像这样…

App.PostRoute = Ember.Route.extend({
    setupController: function(controller, model){
        this._super(controller, model);
        controller.set('post', model);
        controller.set('author', this.get('author'));
    },
    afterModel: function(){
        Ember.run.scheduleOnce('afterRender', this, scrollToNav);
        var self = this;
        var id = this.get('model.authorId');
        return this.store.find('author', id).then(function(result){
            self.set('author', result);
        });
    },
    model: function(params){
        return this.store.find('post', params.id);
    }
});

所以现在发生的是,我正在加载所有帖子的列表作为'blog'的模型。该路由在左侧有一个侧边栏,其中包含所有博客文章的列表,在右侧有一个出口,默认加载"posts"路由。我需要相同的信息为这两条路线,所有帖子的列表,以及作者的信息。输出加载当前帖子并替换'posts'模板,但保留左侧栏上的帖子列表。目前我没有JSON数据侧载,因为我也无法弄清楚,所以现在数据是这样的…

{
    "posts": [
        {
            "id": "1",
            "authorId": "1",
            "title": "Title 1",
            "body": "This is the body 1",
            "uploadDate": "2015-06-03 19:26:15",
            "imageName": "image1.jpg"
        },
        {
            "id": "2",
            "authorId": "2",
            "title": "Title 2",
            "body": "This is the body 2",
            "uploadDate": "2015-06-03 19:26:15",
            "imageName": "image2.jpg"
        }
    ]
}

,然后有一个单独的调用author…

{
    "authors": [
        {
            "id": "1",
            "name": "John Smith",
            "email": "jsmith@gmail.com",
            "imageName": "image1.jpg",
            "gender": "M",
            "bio": "John Smith is an awesome dude who went to awesome school!",
            "facebookUrl": "null",
            "twitterUrl": null,
            "linkedinUrl": null
        }
    ]
}

现在这是我当前的路由对象(在来回浏览了100万个对象之后)。

App.BlogRoute = Ember.Route.extend({
    model: function() {
        var store = this.store;
        var posts = store.findAll('post');
        return posts;
        /* *********************************
        **Tried this, keep getting an error saying 'content.slice' is not a function**
        *
        var authors = store.findAll('author');
         return Ember.RSVP.hash({
            posts: posts,
            authors: authors
        }).then(function(hash){
            return hash;
        }, function(reason){
            console.log(reason);
        });
        ********************************* */
    },
    setupController: function(controller, model) {
        this._super(controller, model);
        controller.set('model', model);
        controller.set('authors', this.get('authors')); //This doesnt do much, and I dont think its necessary.
        /* *********************************
        **Also tried this with the RSVP.hash function, would not render because of 'content.slice' error**
        controller.set('model', model.posts);
        controller.set('authors', model.authors)
        ********************************* */
    },
    afterModel: function(model) {
        Ember.run.scheduleOnce('afterRender', this, scrollToNav);
        var self = this;
        return this.store.findAll('author').then(function(result){
            self.set('authors', result);
        });
    }
});
App.PostsRoute = Ember.Route.extend({
    afterModel: function() {
        Ember.run.scheduleOnce('afterRender', this, scrollToNav);
    },
    model: function() {
        return this.modelFor('blog');
    }
});

当前发生的行为是,除了作者信息外,所有内容都加载到模板中。它只在实际的帖子被访问后加载(例如:'posts/1'),然后从那时起,如果我访问帖子或博客路由,作者名称将留在那里。

我不知道如何使信息一直显示。从我在ember检查器中看到的,两者的数据都被加载了!我想我可能漏掉了一些简单的东西。如果你们有解决办法,请告诉我。

还有一个次要的问题,我敢肯定是有某种联系的。无论我选择什么方法来设置数据到控制器,(例如:controller。我不能在每个循环中通过调用给定的名称来引用模板中的数据。(例如:{{#each posts as |post|}}应该是正确的格式}}如果这不是正确的方式,请纠正我,甚至是什么是预期的方式来做。

仅供参考,以下是博客、帖子和帖子模板的相关部分。

<script type="text/x-handlebars" id="blog">
    <div class="container-fluid">
        <h3>Posts</h3>
        <ul>
            {{#each model as |post|}}
            <li>
                {{#link-to 'post' post}}
                <h3>{{post.title}}</h3>
                <h4>{{post.author.name}}</h4>
                <h5>{{format-date post.date}}</h5>
                {{/link-to}}
            </li>
            {{else}}
                No Models Loaded!
            {{/each}}
        </ul>
    </div>
    <div class="container-fluid">
        {{outlet}}
    </div>
</script>
<script type="text/x-handlebars" id="posts">
    <h1>Recent Blog Posts</h1>
    {{#each model as |post|}}
    <h1>{{post.title}}</h1>
    <h4>By: {{post.author.name}} </h4>
    <h4>Posted: {{format-date post.date}} </h4>
    <img src={{post.imageUrl}} class="img-responsive img-thumbnail">
    <p class="indent">
        {{post.body}}
    </p>
    {{#link-to 'post' post}}Read More{{/link-to}}
    {{/each}}
</script>
<script type="text/x-handlebars" id="post">
    {{#link-to 'posts' class="pull-right"}}<span class="glyphicon glyphicon-chevron-left"></span>Back{{/link-to}}
    <h1>{{post.title}}</h1>
    <h4>Written By: {{author.name}} </h4>
    <h4>Posted: {{format-date post.date}} </h4>
    <hr/>
    <div class="img-container center">
        <img src={{post.imageUrl}} class="img-responsive img-thumbnail">
    </div>
    <br/>
    <p class="indent">
        {{post.body}}
    </p>
</script>

注意:我尝试了几个不同版本的Ember,无论我使用哪个版本,我都得到了"内容"。slice不是一个函数错误,所以我确信我正在做的事情是错误的,但这里有一些额外的信息只是以防万一:D!

VERSION INFO:
Ember Inspector:      1.8.1
Ember:                1.13.0-beta.2+76473dd3
Ember Data:           1.0.0-beta.18
jQuery:               2.1.4

1)我建议你不应该使用store.findAll,因为这是私有api方法。api的链接。正确的方法是用store.find('modelName')代替。例如

model: function() {
  return this.store.find('post'); // promise to find all posts
}

2)如果你想在一个路由中加载所有的文章和作者(例如在博客路由中)

App.BlogRoute = Ember.Route.extend({
  model: function() {
    return Ember.RSVP.hash({
      posts: this.store.find('post'),
      authors: this.store.find('author')
    });
  },
  setupController: function(controller, modelHash) {
    controller.setProperties(modelHash);
    // or directly 
    // controller.set('posts', modelHash.posts);
    // controller.set('authors', modelHash.authors);
    // even
    // this.controllerFor('posts').set('authors', modelHash.authors);
  }
}); 

3)我会简化邮路代码:

App.PostRoute = Ember.Route.extend({
  model: function(params){
    return this.store.find('post', params.id);
  },
  afterModel: function(model){
    var self = this;
    return model.get('author').then(function(author) {
        self.controllerFor('post').set('author', author);
    });
  }
  // setupController not needed here
});

4)你可能需要更多步骤。如果Jsbin能给出准确的答案会很有帮助的。

UPD 08/jun/15: Looks like findAll将很快成为公众https://github.com/emberjs/data/pull/3234。