Search code examples
sproutcoresproutcore-2ember.js

Passing parameters from views to controllers using Sproutcore 2


If I have a controller:

HTH.todosController = SC.ArrayProxy.create({
  content: HTH.store.find(HTH.Todo)
});

I can display all todos doing this:

...
<script type="text/x-handlebars">
  {{#collection contentBinding="HTH.todosController"}}
    {{content}}
  {{/collection}}
</script>
...

But how would I display a todo with a specific ID coming from the view?

...
<script type="text/x-handlebars">
  {{#view contentBinding="HTH.todosController.specific" specificId="1"}}
    {{content}}
  {{/view}}
</script>
...

Solution

  • Here's a solution in jsfiddle allowing you to define the specific id of the todo in the handlebars definition of the view as you have in your example. It's a bit crude, but it works.

    Handlebars:

    <script type="text/x-handlebars">
    {{view App.SpecificIdWrapper}}
    <hr />
    {{#collection App.TodosView contentBinding="App.todosController"}}
        {{content.name}}
    {{/collection}}
    <hr />
    {{view App.SelectedToDoView}}
    </script>
    
    <script type="text/x-handlebars" data-template-name="specificId">
    {{#view App.SpecificIdView dataBinding="App.todosController.content" specificId=3}}
        Specific Todo Id: {{content.id}}
        <br />
        Specific Todo Name: {{content.name}}
    {{/view}}
    </script>
    
    <script type="text/x-handlebars" data-template-name="selectedToDo">
    {{#view contentBinding="App.todosController.selectedToDo.content"}}
      Selected Todo Id: {{content.id}}
    {{/view}}
    

    JavaScript:

    App = Ember.Application.create();
    
    App.SpecificIdWrapper = Ember.View.extend({
        templateName: 'specificId'
    });
    
    App.SpecificIdView = Ember.View.extend({
    content: null,
    data: null,
    specificId: null,
    
    _getTodoById: function() {
        var data = this.get('data'); 
        if(data) {
            for(var i=0;i<data.length;i++) {
                if(data[i].get('id') === this.get('specificId')) {
                    this.set('content', data[i]);
                    break;
                }
            }
        }
    },
    
    // This will make sure the content is set when the view is rendered
    didInsertElement: function() {
        this._getTodoById();
    },
    // And this will update the content whenever specificId is changed
    specificIdDidChange: function() {
        this._getTodoById();
    }.observes('specificId')
    });
    
    App.SelectedToDoView = Ember.View.extend({
        templateName: 'selectedToDo'
    });
    
    App.TodosView = Ember.CollectionView.extend({
    itemViewClass: Ember.View.extend({
        click: function() {
            App.todosController.set('selectedToDo', this);
        }
    })
    });
    
    App.todosController = Ember.ArrayController.create({
    content: [
        Ember.Object.create({id: 1, name: "obj1"}),
        Ember.Object.create({id: 2, name: "obj2"}),
        Ember.Object.create({id: 3, name: "obj3"}),
        Ember.Object.create({id: 4, name: "obj4"}),
        Ember.Object.create({id: 5, name: "obj5"}),
        Ember.Object.create({id: 6, name: "obj6"})
    ],
    selectedToDo: null
    });