Passing parameters from views to controllers using Sproutcore 2
-
22-02-2021 - |
Pregunta
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>
...
Solución
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
});
Otros consejos
Are you thinking about a CRUD style master/details workflow?
If you are, here's a series of tutorials I just wrote for CRUD operations in SC2.
Basically, I attach a double click handler to the table row that triggers a state chart action to display the details in a modal dialog.
CollectionView : SC.CollectionView.extend({
contentBinding: 'App.resultsController',
itemViewClass: SC.View.extend({
tagName: 'tr',
// Spit out the content's index in the array proxy as an attribute of the tr element
attributeBindings: ['contentIndex'],
willInsertElement: function() {
this._super();
// Add handler for double clicking
var id = this.$().attr('id');
this.$().dblclick(function() {
App.statechart.sendAction('showUser', $('#' + this.id).attr('contentIndex'));
});
}
})
Part 4 of the tutorial shows how I did this.
Hope this helps.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow