Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emberjs - Using CollectionView and ItemController together

I have a model Category that has many Documents. When rendering an individual Category I want to list all the the child documents in a drag and drop sortable list. I also want double clicking on any individual document to allow inline editing for that document.

I got both parts working on there own, but can't seem to figure out how to merge them together.

For the sortable list I'm using a custom subclass of CollectionView to render the documents, and after inserting the element I call the html5sortable jquery plugin.

For the inline editing I set an itemController for each document being rendered. Inside the DocumentController I maintained application state of editing the document.

I'm looking for insight on how to combine the two approaches. What I think I need is a way to setup an itemController for each itemView in the CollectionView. I've put the relevant code below.

App.SortableView = Ember.CollectionView.extend({
    tagName: 'ul',
    itemViewClass: 'App.SortableItemView', 

    didInsertElement: function(){
        var view = this;
        Ember.run.next(function() {
        $(view.get('element')).sortable();
        });
    }
});

App.SortableItemView = Ember.View.extend({
    templateName: 'sortable-item',
    doubleClick: function() {
        //This should ideally send 'editDocument' to controller
    }
});

App.DocumentController = Ember.ObjectController.extend({
    isEditing:false,
    editDocument: function () {
        this.set('isEditing', true);
    },
    finishedEditing: function() {
        var model = this.get('model');
        model.get('store').commit();
        this.set('isEditing', false);
    }
});

<script type="text/x-handlebars" data-template-name="category">
    <h1>{{ name }}</h1>

    <h2>Documents</h2>
    <!-- This makes a sortable list -->
    {{view App.SortableView contentBinding="documents"}}

    <!-- This makes an editable list -->
    {{#each documents itemController="document"}}
        <!-- change markup dependent on isEditing being true or false -->
    {{/each}}

    <!-- How do I combine the two -->
</script> 

Thanks for any help. Really appreciate it.

like image 955
raytiley Avatar asked Nov 04 '22 01:11

raytiley


1 Answers

The secret is to set itemController on your ArrayController instead of trying to set it on the view. Then, any views that bind to that ArrayController will get a controller back instead of whatever content is behind it.

To do that, you'll have to make an explicit DocumentsController:

App.DocumentsController = Ember.ArrayController.extend({
    needs: ['category'],
    contentBinding: 'controllers.category.documents',
    itemController: 'document'
});

and then in your categories:

App.CategoryController = Ember.ObjectController.extend({
    needs: ['documents']

Now, in your templates, bind to controllers.documents instead of documents.

like image 137
Christopher Swasey Avatar answered Nov 12 '22 12:11

Christopher Swasey