问题
I want to realize the following concept. Can you give me some hints or keywords at which i should have a look at?
These are my requirements:
- I want to render a list of elements.
- Each element should contain a button. A click on the button should show additional details relating to the clicked element (I do not want to use jquery for a simple hide and show, since this click triggers an additional call to my backend server).
My guess is that it could work like this:
- Implement an ArrayController to control the list of elements.
- The ArrayController should again contain one controller for each of the elements.
- When an element is clicked, the outlet of the elements view should be connected to Controller for the additional details.
These are my problems with that approach:
- Is this a feasible approach at all?
- How can i instantiate multiple controllers and pass my elements to it in my template?
- How can i access the controller for an element, so that i can connect the appropriate controller for the detail view?
Sorry i could no include more Ember Terms in my description. I have just finished the first tutorial and now i need someone to give me the right direction. Thank you! :-)
-----UPDATE------
I worked on this problem myself during the weekend and came up with the following solution. http://jsfiddle.net/mavilein/SNte7/4/
I think the proposed solution by pangratz (first answer) is good, if one has a simple model like the one he has used. When i saw his answer, i realized that i did not describe my requirements detailed enough. Actually my requirements looks like this:
Initial state of the list
- First Element
- Second Element
- Third Element
After clicking e.g. Item 3, it should show the associated Items of it:
- First Element
- Second Element
- Third Element
- Associated Item 1 for third Element
- Associated Item 2 for third Element
Therefore i wanted to have a separate Controller to control the associated Items of my elements in the list. It seemed to me that outlets were the right way to go.
Actually i had to patch the ember framework to implement the desired behaviour. Currently i call this feature 'Dynamic Outlet Names'. Currently one can specify outlet names in a HandleBars template, but one cannot use properties of an object to generate those names dynamically. I patched the outlet helper to evaluate wether the String parameter represents a property of an object:
Ember.Handlebars.registerHelper('outlet', function(property, options) {
if(arguments.length === 3){
var optionsTemp = arguments[arguments.length - 1],
context = arguments[0];
var temp = Ember.Handlebars.get(this, context, optionsTemp);
if(temp)
property = temp;
options = optionsTemp;
}else if (property && property.data && property.data.isRenderData) {
options = property;
property = 'view';
}
options.hash.currentViewBinding = "controller." + property;
return Ember.Handlebars.helpers.view.call(this, Ember.ContainerView, options);
});
That way i am able to use an objects property as a value for an outlet name.
<script type="text/x-handlebars" data-template-name="items" >
{{#each item in controller}}
{{item.description}}
<button {{action showAssociatedItems item}}>Show Associated Items</button>
{{outlet item.id asd}}
{{/each}}
</script>
See my full working example here: http://jsfiddle.net/mavilein/SNte7/4/
My Question: What do you think of this solution? Could i have implemented it without patching the framework? As i said, the first proposed solution is good for a simple model. But my feeling is that the associated items should be realised as models and should therefore be controlled by an Ember Controller.
回答1:
I would use an ArrayController
which holds all elements which shall be shown. The setting - wether the details of an object shall be shown or not - should in my opinion be handled by the view, so I wouldn't create a controller instance for each item. The view which shows a single item shall keep the bookmarking wether the details are shown or not. So you could do something along the following lines, see http://jsfiddle.net/pangratz666/ASHFa/:
Handlebars:
<script type="text/x-handlebars" data-template-name="items" >
{{#each item in controller itemViewClass="App.ItemView"}}
{{item.description}} <button {{action toggleDetail}}>{{view.toggleDetailText}}</button>
{{#if view.showDetail}}
<img {{bindAttr src="item.img"}}>
{{/if}}
{{/each}}
</script>
JavaScript:
App = Ember.Application.create({});
App.ItemsView = Ember.View.extend({
templateName: 'items'
});
App.ItemView = Ember.View.extend({
toggleDetailText: function() {
return this.get('showDetail') ? 'hide' : 'show';
}.property('showDetail'),
toggleDetail: function() {
this.toggleProperty('showDetail');
}
});
App.itemsController = Ember.ArrayController.create({
content: [{
description: 'first item',
img: 'http://25.media.tumblr.com/tumblr_ll3y1pZDVJ1qb08qmo1_250.jpg'
}, {
description: 'second item',
img: 'http://24.media.tumblr.com/tumblr_lk7u170Ztt1qb33vho1_250.jpg'
}, {
description: 'third item',
img: 'http://25.media.tumblr.com/tumblr_lj5367UKg11qzgqodo1_250.jpg'
}]
});
App.ItemsView.create({
controllerBinding: 'App.itemsController'
}).append();
来源:https://stackoverflow.com/questions/13056851/how-to-implement-a-list-of-multiple-elements-where-an-element-can-be-expanded-b