【问题标题】:Backbone collection only renders on page load but not when coming from a different routeBackbone 集合仅在页面加载时呈现,但在来自不同路由时不呈现
【发布时间】:2017-07-18 17:11:23
【问题描述】:

我正在尝试将 Backbone 与 requirejs 一起使用,到目前为止它工作得很好,而且我使用了一个非常干净的样板,但现在我也想开始使用 Backbone 处理视图和模型的方式,这是我以前没有的,并且我的大厅表视图在页面加载时呈现得很好,但是一旦我更改页面并返回它,它就不会呈现任何内容。没有给出错误,并且该集合似乎可以很好地获取新数据。它与在 main.js 中渲染基本表结构,然后在不告诉父视图的情况下在 views/play.js 中创建子视图有什么关系吗?

骨干路由器(main.js)

play: function() {
    var view = new app.Views.Play();
    app.instance.changePage(view);
    require(['controllers/play'], function(PlayController) {
        PlayController.init();
    });
},

…

app.Views.App = app.Extensions.View.extend({

  el: 'body',

  changePage: function(view) {

    var previous = this.currentPage || null;
    var next = view;

    if(previous) {
      if(AppLib.transitions === "notransitions") previous.remove();
      previous.transitionOut(function() {
        previous.remove();
      });
    }

    next.render({ page: true });
    this.$el.append(next.$el);

    next.transitionIn();
    this.currentPage = next;

    // Change page title
    var title = app.lang.get(next.className + ".title");
    if(title === next.className + ".title") title = next.className;
    document.title = (!_.isEmpty(Backbone.history.getFragment()) ? title.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}) : AppLib.name);

  }

});

…

app.Views.Play = app.Extensions.View.extend({

  className: 'play',
  addHeader: function() {
    var options = { className: "gl-header", fixed: true, elements: ['BackButton', 'LoginButton'] };
    var n = new app.Views.Header({ el: "." + this.className, parentView: this, options: options });
    this.$el.prepend(n.render());
  },

  render: function() {
    var template = _.template($('script[name=play]').html());
    this.$el.html(template());
    this.addHeader();
    return app.Extensions.View.prototype.render.apply(this, arguments);
  }

});

播放控制器(controllers/play.js)

define(['jquery', 'backbone', 'models/play', 'views/play'], function($, Backbone, Model, View) {
    return {
        init: function() { 
            var LobbyCollection = new Model.LobbyCollection();
                LobbyCollection.getMatches();

            var LobbyView = new View.Lobby({ collection: LobbyCollection });
        }
    }
}); 

播放模型(models/play.js)

define(['jquery', 'backbone', 'persist', 'AppLib'], function($, Backbone, Persist, AppLib) {
var Match = Backbone.Model.extend({});

  var LobbyCollection = Backbone.Collection.extend({
    model: Match,
    url: "/api/v1/play/lobby-updates",
    initialize: function() {

    },
    getMatches: function(callback) {
      var self = this;
      this.fetch({ 
        reset: true,
        success: function(collection, response, options) {
          self.trigger('successOnFetch');
        },
        error: function(collection, response, options) {
          self.trigger('errorOnFetch');
        }  
      });
    },
    parse: function(response) {
      var obj = response["lobby_matches"];
      this.RandomLobbyName = response["random_name"];
      return _.map(obj, function(value, key) {
        return obj[key];
      });
    }
  });

  return {
    LobbyCollection: LobbyCollection
  }
});

播放视图 (views/play.js)

define(['jquery', 'backbone', 'persist', 'AppLib', 'jquery_debounce'], function($, Backbone, Persist, AppLib) {

var LobbyView = Backbone.View.extend({
    el: **$(".play.page-container .table")** !!".play.page-container .table",
    initialize: function() {
      var self = this;

      this.listenTo(this.collection, 'reset', this.render);
      this.listenTo(this.collection, 'successOnFetch', this.handleSuccess);
      this.listenTo(this.collection, 'errorOnFetch', this.handleError);

      $(".play.page-container .table button.refresh-list").on("click", $.throttle(2000, function() {
        $(this).html($("<span\>", { "class": "opaque blue throbber small" })).addClass("selected").prop("disabled", true);
        self.collection.getMatches();
      }));
    },
    handleSuccess: function(options) {
      setTimeout(function() { 
        $(".play.page-container .table button.refresh-list").removeClass("selected").removeAttr("disabled").html($("<span\>", { "class": "icon-spinner6" }));
  }, 2000);
    },
    handleError: function(options) {

    },
    render: function() {
      var template = _.template($('script[name=lobby-table]').html());
      var $tbody = this.$el.children("tbody");
          $tbody.children().not(".create-lobby").remove();
          $tbody.append(template({ collection: this.collection.toJSON() }));
      return this;
    }
});

return {
    Lobby: LobbyView
}

});

【问题讨论】:

  • **$(".play.page-container .table")** !!".play.page-container .table" 应该是什么?我不认为这个问题和答案对其他人有用,但你,最好删除它而不是回答它

标签: javascript backbone.js collections render subviews


【解决方案1】:

我自己解决了。问题是我查找了如何在此处创建视图,他们使用 jquery 定义了元素: el: $("selector") 并且我遵循了它,但这是错误的。 Backbone 已经将它放入 jquery 本身,所以它是双倍的。所以我简单地将我的选择器放在引号中,现在一切正常。

【讨论】:

  • 将 jQuery 对象传递给 jQuery 构造函数不会改变任何东西
  • @TJ 为我修复了它。也许在以前版本的 Backbone 中这并不重要。
猜你喜欢
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 2017-05-25
  • 2021-06-09
  • 2019-08-19
  • 1970-01-01
  • 2017-05-29
  • 2020-07-21
相关资源
最近更新 更多