使用骨干路由器的正确方法是什么?

时间:2015-05-24 17:40:26

标签: javascript jquery backbone.js optimization sqlite

我的骨干路由器中有当前正在运行的代码段...

var currentView;
var DishRoutes = Backbone.Router.extend({
  routes: {
   'dishes': 'allDishes',
   'dishes/': 'allDishes',
  },

  //Show all current dishes on path /dishes 
  allDishes: function () {
   $("#add_a_menu_link").show();
   if (currentView !== undefined) {
    currentView.remove();
   }
   $("#contentArea").empty();
   $("#contentArea").append("<div id=contents></div>");
   dishes.fetch({
    success: function () {
     console.log(dishes);
     currentView = new AllDishesView({
      collection: dishes
      //passes an x so that it will show all the views not just that specific's menus dish...
     }).render("x");
    },
    error: function () {
     console.log("couldn't find dishes:(");
    }
   });
  },

等......还有许多其他路由,每个路由都有类似的事情发生在骨干路由器上。

var AllDishesView = Backbone.View.extend({
 el: "div#contents",

 initialize: function () {
  console.log(this);
  this.$el.append(this.nDish);
  this.listenTo(this.collection, "add change remove", this.render);
 },

 nDish: $("<ul id='dishlist'></ul>"),
 template: _.template($('#dishTemplate').html()),
 //Render function renders either all or within a passed in parameter...
 render: function (anID) {
  console.log(this);
  var temp = this.template;
  var newDL = this.nDish;
  newDL.empty();
  console.log(anID);
  this.$el.append($('<a href="/dishes/new"></a>'));
  dishes.forEach(function (sDish) {
   //Was this rendering passed with an id?
   var zDish = sDish.toJSON();
   if (anID === "x") {
    console.log(zDish.menu_id);
    newDL.append(temp({
     dish: zDish
    }));
    //If so show only dishes belonging to that Menu!
   } else {
    $("#contents").append($('<a id="add_a_dish_link" href="/#menus/'+anID+'/dishes/add">+ Dish</a>'));
    if (parseInt(zDish.menu_id,10) === parseInt(anID,10)) {
     newDL.append(temp({
      dish: zDish
     }));
    } else {
     console.log("NOT A MATCH!");
    }
   }
  });
  return this;
 }
});

以下是相关的HTML部分......

<div id="contentArea">

 </div>
<script type="text/template" id="dishTemplate">
  <li>
   <a href="/#dishes/<%= dish.id %>/">
    <%- dish.name %>
   </a>
  </li>
 </script>

虽然这种方法的作用是100%清除我的contentArea中的任何内容,然后添加一个新的div内容,其中包含我想要的任何东西......我喜欢它,因为它是完全证明并且可重复使用...我不喜欢它因为这似乎效率低下。我最近听说过我应该尝试从jQuery使用.detach然后找到一种方法来重新附加它,当我想要显示该视图但我不知道如何做到这一点没有主要的范围问题...

或者,如果有人知道如何轻松实施的最佳做法: 清除此内容区域... 放入这个新内容 它出现在路由器上。使用最有效的策略,需要最少量的DOM重新呈现,如果可能的话,如果我回到allDishes,则不需要额外的获取。谢谢!

1 个答案:

答案 0 :(得分:0)

仅使用App路由器来路由您的应用程序,所有数据提取都必须在视图中完成以保持代码清洁。

只需在路由器中创建一个DishView。不要添加任何逻辑,保持清洁。

 allDishes: function () {
  // Your Dom operations here
  currentView = new AllDishesView({});
  // Now just create a View and attach to DOM.

  },

现在在您的视图中获取您的收藏

var AllDishesView = Backbone.View.extend({
 el: "div#contents",

     initialize: function () {
      this.$el.append(this.nDish);
      this.collection = new DishCollection();
      this.listenTo(this.collection, "add change remove sync", this.render);
      //render on collection on sync also
     },

现在,approuter中的逻辑被最小化 如果你不想每次只检查你的视图实例,那么只要将它添加到DOM中。喜欢(在路由器中)

 allDishes: function () {
  // Your Dom operations here
  if(.isUndefined(this.currentView){ 
    this.currentView = new AllDishesView({});
  }else{
      // Just add it back to the DOM
        $("#contentArea").append(this.currentView.el)   
  }
  // Now just create a View and attach to DOM.

  },

这里可以添加许多最佳实践和优化,但这将是一个很重要的列表。

注意:如果要将视图附加到DOM,请使用deleagteEvents,否则视图的事件将无效。