1

我正在创建一个主干应用程序,尽管一切似乎都正常,但如果我继续使用这种方法添加功能和视图,我担心我可能需要很快重构。我在后端使用Parse,这意味着该对象Parse等效于Backbone.Model. 我无法控制我的模型,因为它们已经针对移动设备进行了优化,在这里我只需要显示 3 个不同模型的某些关键值。

虽然没有什么“错误”(它有效),但我开始犯“更大”的错误只是时间问题。

这是我的Router

App.Controllers.Documents = Backbone.Router.extend({
    routes:{
        "story/:id" : "fullStory",
        "" : "index"
    },
// ...
   fullStory: function(id){
     var self = this;
     var query = new Parse.Query(Steps);
     query.equalTo("story", id)
     var steps = query.collection();

     steps.fetch({
       success: function() {

         new App.Views.Steps({ collection: steps });

         var title = new Story({ objectId: id });
         title.fetch({
              success: function(model, resp) {
              new App.Views.Title({ model: title});
              var idUser = title.toJSON().idUser;
              var user = new Parse.User({ objectId: idUser });
              user.fetch({
                  success: function(){
                         // I just need the username key here...
                     new App.Views.Username({model:user,el:$("#user")});
                  },
                  error: function(){
                     new Error({ message: 'Could not find the user you requested.' });
                  }
               })
             },
              error: function() {
                new Error({ message: 'Could not find that story.' });

               }
          })
        },
        error: function() {
          new Error({ message: "Error loading story." });
        }
      });
}

鉴于在Parse中创建对象的方式,我需要访问 3 个不同的对象,这就是我渲染View“部分”的原因。我希望这个函数只在FullStory View其中呈现这些“子视图”,但我不确定如何做到这一点,因为Parse.Objects 需要对另一个对象的引用->另一个对象的键var user = new Parse.User({ objectId: idUser });在哪里。idUser

最后我的Views

App.Views.Steps = Backbone.View.extend({
  tagName : "ul",
  className: "steps",
  initialize: function() {
    this.render();
  },
  render: function() {
    this.$el.html(_.template($("#story_steps").html())({ collection: this.collection }));
    $('#steps_wrapper').html(this.el);
  },
});

App.Views.Title = Backbone.View.extend({
  initialize: function() {
    this.render();
  },
  render: function() {
    this.$el.html(_.template($("#story_title").html())({ model: this.model }));
    $('#title').html(this.el);
  }
});
App.Views.Username = Backbone.View.extend({
  initialize: function() {
   this.render();
  },
  template: _.template('<%= name %>'),

  render: function() {
  this.$el.html(this.template(this.model.toJSON()));
  }
});
4

1 回答 1

6

你以错误的方式解决这个问题。您的路由器应该是几行代码来进行初始视图/收集,并可能进行 fetch 调用。大多数功能应该在您的视图中。

你的路由器应该这样做

fullStory: function(id){
     var self = this;
     var query = new Parse.Query(Steps);// not sure what this does
     query.equalTo("story", id) // This does nothing!
     var stepsCollection = query.collection();
     var stepsView = new App.View.Steps({collection: stepsCollection});
     stepsCollection.fetch() // you could also do this in initialize()
}

现在您需要知道的是,collection.fetch() 会触发集合上的“重置”事件,该事件会冒泡到视图中,您可以在其中处理它。因此,在视图中侦听您的“重置”事件并处理它,然后重新渲染:

App.Views.Steps = Backbone.View.extend({
  tagName : "ul",
  className: "steps",
  initialize: function() {
      this.bindAll(this, 'render');
    this.collection.bind('reset', this.render);
  },
  render: function() {
    this.$el.html(_.template($("#story_steps").html())({ collection: this.collection }));
    $('#steps_wrapper').html(this.el);
  },
});

请记住 StepsView 的单一职责原则 负责渲染和处理 Steps(无论它们是什么)及其各自的模型/集合的事件。用户名视图负责渲染和处理与用户名有关的一切。目前,所有事情的责任都在您的路由器中实现,这种方法是完全错误的。

我会质疑您是否需要单独的 USername 和 Title 视图——这些应该作为更广泛视图的模板的一部分呈现出来——而不是它们自己的视图——它们什么都不做。

我感觉到您闻到了不对劲,这就是您发布问题的原因。我会进行重大的重构 - 将您的路由器减少到几行......您的视图将永远是主干中最大的类。

如果你想快速确定骨干,我强烈推荐优秀的 peepcode 截屏视频:

https://peepcode.com/products/backbone-js https://peepcode.com/products/backbone-ii https://peepcode.com/products/backbone-iii

您将在大约 3 小时内以 30 美元的价格了解所有内容

于 2012-07-05T10:40:21.280 回答