How to implement a list of multiple elements, where an element can be expanded by click? (Dynamic Outlet Names?)

大憨熊 提交于 2020-01-04 06:49:08

问题


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:

  1. Is this a feasible approach at all?
  2. How can i instantiate multiple controllers and pass my elements to it in my template?
  3. 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

  1. First Element
  2. Second Element
  3. Third Element

After clicking e.g. Item 3, it should show the associated Items of it:

  1. First Element
  2. Second Element
  3. 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!