I'm running into a weird issue. I have a Marionette module responsible for fetching data, which is exposed through Backbone.Wreqr Request/Response system. For my projects it looks like this (CoffeeScript):

@App.module 'Entities', (Entities, App, Backbone, Marionette, $, _) ->

    class Entities.Project extends Backbone.Model
        urlRoot: '/api/project'

    class Entities.ProjectsCollection extends Backbone.Collection
        model: Entities.Project
        url: '/api/projects.json'

    API =
        getProjectEntities: ->
            projects = new Entities.ProjectsCollection
            projects.fetch()
            projects

        getProject: (project) ->
            project = new Entities.Project({ id: project });
            project.fetch()
            project


    App.reqres.setHandler 'project:entities', ->
        API.getProjectEntities()

    App.reqres.setHandler 'project:entity', (project) ->
        API.getProject(project)

For the collection this works entirely as expected. Data is fetched, and when I pass it to a Marionette.CompositeView the view is rendered just fine.

I'm fleshing out a detail-page for these projects now, and all is not well. When I request a specific model by instantiating a new model currentProject = App.request 'project:entity', project, and then pass it on to a Marionette.ItemView, the ItemView parses its template before the model is fetched, causing an Uncaught reference error because the variables in my template haven't been declared yet... Any idea what's going on here?

My template is for now extremely simple:

    <script id="project_detail_template" type="text/template">
        <h1>Hello world!</h1>
        <p><%= title %></p>
    </script>

Edit: Ok, apparently I'm doing more things wrong here, because when I log out this model to the console, all it has attribute-wise is its id. If someone could set me in the right direction that'd be great.

有帮助吗?

解决方案

You're calling fetch and then immediately returning the project object, without waiting for the async fetch to complete.

Instead of returning the project object, return project.fetch() as this will return a promise. Then you can .then the value, ensuring it is available:


@App.module 'Entities', (Entities, App, Backbone, Marionette, $, _) ->

    class Entities.Project extends Backbone.Model
        urlRoot: '/api/project'

    class Entities.ProjectsCollection extends Backbone.Collection
        model: Entities.Project
        url: '/api/projects.json'

    API =
        getProjectEntities: ->
            projects = new Entities.ProjectsCollection
            projects.fetch()

        getProject: (project) ->
            project = new Entities.Project({ id: project });
            project.fetch()


    App.reqres.setHandler 'project:entities', ->
        API.getProjectEntities()

    App.reqres.setHandler 'project:entity', (project) ->
        API.getProject(project)

When making the call through reqres, you'll get a promise back.


App.request("project:entity", someId, function (promise){

  // wait for the project to finish loading

  $.when(promise).then(function(project){
    // do stuff with your project, here
  });

});
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top