Backbone.js中主从细节场景的首选模式

时间:2012-07-23 00:38:45

标签: javascript backbone.js

大多数处理主细节场景的Backbone教程通过使用从路径(example)传递的模型创建新视图来处理细节状态。我想知道替代选项是什么,每种选择的利弊是什么。

对我来说,这种实例化新视图的方法总是让我感到惊讶的是,它似乎错过了利用Backbone模型视图绑定的机会。即,创建基于所选模型更新的单个详细视图。但这需要一个仅与UI /活动状态有关的单独模型。

我可以想到三种不同的模式:

  • 为每个活动详细信息创建/销毁视图。 (这似乎是多余的工作,更不用说潜在的zombie problems
  • 维护一个表示活动详细信息的附加模型,并创建一个在模型更新时重新呈现的视图
  • 使用交换关联模型的方法创建一个视图(我认为这可能导致事件绑定问题并且可能不是一个好主意)

在像上面链接的示例教程这样的简单案例的上下文中,有哪些优缺点?在#2中使用UI模型的想法是不好的做法?还有其他解决方案吗?

1 个答案:

答案 0 :(得分:1)

根据我的经验,UI模型非常有用。我们在应用中为每个“页面”维护ContextModel。真正好的是我们保证用完整的ContextModel初始化“页面”,因此最初只创建一个上下文。

我们的AppView始终处理在触发特定路线时为页面创建初始上下文。路由处理程序将设置上下文的默认值,并根据路由的值解析事物。

页面本身一旦初始化,它只需要担心ContextModel的更改,并让处理程序进行必要的更新,然后更新路径。

以下是我们AppView直接提取的示例:

onSomeRoute : function (project, category, pivot, tab, item) {

  // Setup page context with defaults.
  var options = {
    category : 'traits',
    tab      : 'population',
    item     : null
  };

  // Figure out what the allowed categories and tabs are from this
  // environment by checking against all schema items.
  [snipped]

  // Resolve the `category` and the `pivot`. Try and match the pivot's
  // slug, else choose the first pivot in the category.
  if (_(categories).contains(category)) options.category = category;

  [snipped]

  if (pivots) options.pivot = pivots.find({ slug : pivot }) || pivots.first();

  // Resolve the `tab` and `item`. Only allow valid tabs, and then try
  // to match the item's slug as well, or choose the first one.
  var tabs = ['population', 'sources', 'engagement', 'retention'];
  if (_(tabs).contains(tab)) options.tab = tab;
  [snipped]

  // Now that we've applied some defaults, make sure the path is
  // updated to reflect what the interface is showing.
  [snipped]

  this.loadPage('some-page', options);
}

然后在PageView中我们有几个更改处理程序:

// When category changes, try to match the current pivot against pivots
// in the category, else choose the first pivot from the category.
onCategoryChange : function (context, category) {
  var schema = this.context.get('environment').get(category);
  if (!schema.contains(this.context.get('pivot')))
    this.context.set('pivot', schema.first());

  this.router.update({
    category : category
  });
},

// When the pivot changes, create a new set of segments for the context.
onPivotChange : function (context, pivot) {
  Segmenter.segment(context, function (segments) {
    context.get('segments').reset(segments).each(function (segment) {
      segment.evaluate();
    });
  });

  this.router.update({
    pivot : pivot.get('slug')
  });
},

请注意,所有更改处理程序都会根据上下文中的更改保持页面的URL更新。 (我们在路由器上写了几个自定义方法,这对我们来说非常简单。)但是他们也做了我们需要为页面发生的任何其他逻辑。

希望其中一些有助于为您提供想法。通常,存储在URL中的任何状态都在我们的PageContext中,然后为了方便起见,还存储了从该状态派生的其他一些东西。