Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create links programmatically inside an EmberJS view

Tags:

views

ember.js

I have a pretty complex view to render which involves some kind of recursion (the typical folder/file nested list). The fact that it contains heterogeneous objects (folders and files) make it even harder to write Handlebars templates.

Therefore, the only solution I've found is to create a view, and manually fill the render buffer. I came with the following solution:

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

  nameChanged: function() {
    this.rerender();
  }.observes('[email protected]'),

  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>');
  }
});

Now, what I'd like is to be able to add links so that each folder and each file is clickable and redirect to another route. But how am I supposed to do that, as I don't have access to the linkTo helper? I've tried to play with the LinkView view, but without any success. Should I register handlers manually for each item?

I've also thought about breaking that with a CollectionView instead, and splitting the content by depth so that I could render it using templates, but it seems more complicated.

Any thoughts?

like image 201
Michael Gallego Avatar asked Oct 04 '22 16:10

Michael Gallego


1 Answers

It occurs to me that the linkTo helper may not be the best way to approach this. All the linkTo does is router.transitionTo, dynamically resolving paths as needed plus the automatic active css property setup.

In your case, you already have the items list and hence the clicked item accessible within the View itself. So creating a LinkView dynamically or implicitly via the {{#linkTo}} helper to then handle the item that was clicked may not be necessary.

I would directly setup old-skool data-some-id on the generated item anchor. Then in the view handle the click, compute which item it corresponds to using dataset.someId and then transitionToRoute to that item, either directly in the view or via a gotoItem on the controller.

If there are many such items, this would have significant savings, on the number of DOM elements and Ember Views.

I tried this with a similar setup in this jsbin. I have used a ProductsListView with a template, but the approach would be similar with a programmatic View as in your example.

like image 172
Darshan Sawardekar Avatar answered Oct 07 '22 20:10

Darshan Sawardekar