如何使用骨干模型中的下划线模板标签?

时间:2014-04-25 21:00:44

标签: javascript json backbone.js underscore.js marionette

我使用来自api http://date.jsontest.com/

的json有一个非常小的简单时间应用程序

基本上一切都有效,除了从模型中调用模板内的json值

   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();

然后在我的模板中我有了这个

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

我没有错误,没有显示任何内容,但函数内部的console.log(apiTime.attributes.time)正常显示

如果我输入TodaysTime.attributes.time,控制台内的

也可以 但如果我尝试<p><%- TodaysTime.attributes.time %> </p>,我会得到默认值Now

从模型中显示价值的正确方法是什么?

Github链接测试https://github.com/nolawi/time-machine-test

1 个答案:

答案 0 :(得分:1)

这是因为您在从服务器获取数据之前呈现模型。这就是您看到默认值的原因。您应该在模型,承诺或回调上使用侦听器。以下是如何解决的问题:

      ...
      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
      });
      ...

评论后编辑: 嗯,这真的取决于你的情况。有些人在路线中移动了这个逻辑。您只需添加初始化功能(但首先从 onRender 删除 fetch )到 ItemView 。类似的东西:

initialize: function () {
                this.model.on('sync', this.render, this);
                this.model.fetch({ reset: true, change: true });
                return this;
              }