Pregunta

I have a very small simple time app using json from an api http://date.jsontest.com/

Essentially everything works except calling the json value inside the template from the model

   var Time = new Marionette.Application();

  Time.addRegions({
      mainRegion: "#main-region"
  });

  TimeModel = Backbone.Model.extend({
      defaults: {
          time: "Now",
          milliseconds_since_epoch: 1234,
          date: "Today"
      },
      urlRoot: 'http://date.jsontest.com/'

  });
  var TodaysTime = new TimeModel();

  TimeView = Marionette.ItemView.extend({
      template: "#template",
      model: TodaysTime,

      onRender: function () {
             TodaysTime.fetch({
                 success: function (apiTime) {
                  console.log(apiTime.attributes.time);
                  TodaysTime = apiTime;
              }
          });
      }

  });

  var timeView = new TimeView();
  Time.mainRegion.show(timeView);
  Time.start();

And then in my template I have this

<p><%- time %> <%- milliseconds_since_epoch %></p>

I get no errors and nothing is displaying but the console.log(apiTime.attributes.time) that is inside the function works

inside the console if i type this TodaysTime.attributes.time it also works but if i try <p><%- TodaysTime.attributes.time %> </p> I get the default value Now

What is the proper way to display value from a model?

Github link to test https://github.com/nolawi/time-machine-test

¿Fue útil?

Solución

this happens because you render the model before you fetch the data from the server. That's why you see the default values. You should use listeners on model, promises or callbacks. Here's how it could be fixed:

      ...
      var TodaysTime = new TimeModel();
      TodaysTime.fetch().done(function(){Time.mainRegion.show(timeView);});

      TimeView = Marionette.ItemView.extend({
          template: "#template",
          onRender: function() {
              console.log('rendered');
              TodaysTime.fetch({
                  success: function(apiTime) {
                      console.log(apiTime.attributes.time);
                  }

              });
          }

      });

      var timeView = new TimeView({
        model: TodaysTime
      });
      ...

Edit after you comment: Well, it really depends on your case. Some move this logic in routes for example. You can just add initialize function (but remove fetch from onRender first) to you ItemView. Something like:

initialize: function () {
                this.model.on('sync', this.render, this);
                this.model.fetch({ reset: true, change: true });
                return this;
              }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top