在EmberJS视图中以编程方式创建链接

时间:2013-06-30 10:19:08

标签: ember.js views

我有一个非常复杂的渲染视图,它涉及某种递归(典型的文件夹/文件嵌套列表)。它包含异构对象(文件夹和文件)这一事实使得编写Handlebars模板变得更加困难。

因此,我发现的唯一解决方案是创建一个视图,并手动填充渲染缓冲区。我带来了以下解决方案:

App.LibraryContentList = Ember.View.extend({
  tagName: 'ol',
  classNames: ['project-list', 'dd-list'],

  nameChanged: function() {
    this.rerender();
  }.observes('content.@each.name'),

  render: function(buffer) {
    // We only start with depth of zero
    var content = this.get('content').filterProperty('depth', 0);

    content.forEach(function(item) {
      this.renderItem(buffer, item);
    }, this);
  },

  renderItem: function(buffer, item) {
    switch (item.constructor.toString()) {
      case 'App.Folder':
        this.renderFolder(buffer, item);
        break;
      case 'App.File':
        this.renderFile(buffer, item);
        break;
    }
  },

  renderFolder: function(buffer, folder) {
    buffer.push('<li class="folder dd-item">');
    buffer.push('<span class="dd-handle">' + folder.get('name') + '</span>');

    // Merge sub folders and files, and sort them by sort order
    var content = this.mergeAndSort();

    if (content.get('length') > 0) {
      buffer.push('<ol>');

      content.forEach(function(item) {
        this.renderItem(buffer, item);
      }, this);

      buffer.push('</ol>');
    }

    buffer.push('</li>');
  },

  renderFile: function(buffer, album) {
    buffer.push('<li class="album dd-item">');
    buffer.push('<span class="dd-handle">' + file.get('name') + '</span>');
    buffer.push('</li>');
  }
});

现在,我想要的是能够添加链接,以便每个文件夹和每个文件都可以点击并重定向到另一个路径。但我怎么能这样做,因为我无法访问linkTo帮助器?我试过使用LinkView视图,但没有任何成功。我应该为每个项目手动注册处理程序吗?

我还考虑过用CollectionView打破它,然后按深度拆分内容,以便我可以使用模板渲染它,但它看起来更复杂。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

我认为linkTo助手可能不是解决此问题的最佳方法。 linkTo所做的只有router.transitionTo,根据需要动态解析路径以及自动active css属性设置。

在您的情况下,您已经拥有了项目列表,因此可以在视图本身中访问所单击的项目。因此,通过LinkView帮助程序动态或隐式地创建{{#linkTo}},然后处理被单击的项可能没有必要。

我会在生成的项目锚点上直接设置old-skool data-some-id。然后在视图中处理点击,直接在视图中或通过控制器上的dataset.someId计算使用transitionToRoute然后gotoItem对应的项目。

如果有很多这样的项目,这将大大节省DOM元素和Ember Views的数量。

我在此jsbin中使用类似的设置尝试了此操作。我使用了ProductsListView一个模板,但该方法与您的示例中的程序化View类似。