Best way to implement tabpanel in ember?

I'm new to ember and trying to create a web application driven by Ember. I read various articles and studied several examples. The basic concepts are clear, but now I'm trying to implement a tabpanel. My approach is this:

View

Configurator.TabPanelView = Ember.View.extend({ classNames: ['tabPanel'], templateName: 'tabPanel' }); 

Template

 <script type="text/x-handlebars" data-template-name='tabPanel'> <div class='tabHead'> <ul> {{#each tabViews}} <li {{action "{{this.actionName}}" target="{{this.value}}"}} >{{this.title}}</li> {{/each}} </ul> <div class="tab-content">{{outlet}}</div> </div> </script> 

Application Use

 var tab= Configurator.TabPanelView.create({ classNames: ['assortment'], tabViews: [{ title: 'First', value:'Foo', actionName: 'firstTab' },{title: 'Second', value:'Foo', actionName: 'secondTab' }], firstTab: Ember.View.extend({ templateName: 'first' }), secondTab: Ember.View.extend({ templateName: 'second' }) }); tab.appendTo("body"); 

TabTemplate renders correctly, but if I try to click on li elements, the next error will be reset

Fault Error: approval failed: Target <(subclass of Ember.View): ember217> has no action {{this.actionName}}

I am also wondering if I should use a router to implement tabs. But as far as I see, routers operate at the application level and are intended for use in a single UI.

+7
source share
3 answers

The problem is in your template:

 <li {{action "{{this.actionName}}" target="{{this.value}}"}} >{{this.title}}</li> 

AFAIK, actions cannot be connected, so when you write this, it tries to call the {{this.actionName}} method instead of firstTab , for example.

I think this is a typical example where you should use Ember.CollectionView with itemViewClass , which has a click method that is:

 App.MyCollectionView = Ember.CollectionView.extend({ tagName: 'ul', templateName: 'the-template-name', itemViewClass: Ember.View.extend({ click: function() { var actionName = this.get('content.actionName'), target = this.get('controller.target'); target.send(actionName); } }) }); 

The code above is certainly not right, but the idea is here.

But I think Router is the right way to do this. I suggest you take a look at the @Ghempton Ember Router example , where it defines a tab with Ember.Router .

+2
source

You have 2 options:

1) each tab has its own controller, view and must also be defined in the router

 <script type="text/x-handlebars" data-template-name="tabs"> <div> <ul class="nav nav-tabs"> {{#view Bootstrap.TabItem item="info"}} <a {{action gotoInfo}}>Info</a> {{/view}} {{#view Bootstrap.TabItem item="anamnese"}} <a {{action gotoAnamnese}}>Anamnese</a> {{/view}} {{#view Bootstrap.TabItem item="medication"}} <a {{action gotoMedication}}>Medication</a> {{/view}} </ul> {{outlet}} </div> </script> Bootstrap.TabItem = Ember.View.extend({ tagName: 'li', classNameBindings: ['isActive:active'], isActive: function() { return this.get('item') === this.get('controller.selectedTab'); }.property('item', 'controller.selectedTab').cacheable() }); 

2) all tabs are in one large view, and tabs will be hidden or shown

 {{#view Ember.TabContainerView currentView="info"}} <ul class="nav nav-tabs"> {{#view Bootstrap.TabView value="info"}}<a>Info</a>{{/view}} {{#view Bootstrap.TabView value="anamnese"}}<a>Anamnese</a>{{/view}} {{#view Bootstrap.TabView value="medication"}}<a>Medication</a>{{/view}} </ul> {{#view Ember.TabPaneView viewName="info"}} {{view EEPD.InfoView}} {{/view}} {{#view Ember.TabPaneView viewName="anamnese"}} {{view EEPD.AnamneseView}} {{/view}} {{#view Ember.TabPaneView viewName="medication"}} {{view EEPD.MedicationView}} {{/view}} {{/view}} Bootstrap.TabView = Ember.TabView.extend({ tagName: 'li', classNameBindings: ['isActive:active'], isActive: function() { return this.get('value') === this.get('tabsContainer.currentView'); }.property('tabsContainer.currentView').cacheable() }); 
+1
source

There are two ways to implement a tab bar.

If you want your bookmarks to be classified, you must implement them using Router:

Patterns

 <script type="text/x-handlebars" data-template-name="application"> <div class="tabpanel"> <div class="tabs"> <div {{action "goToFirstTab"}}>First tab</div> <div {{action "goToSecondTab"}}>Second tab</div> </div> {{outlet}} </div> </script> <script type="text/x-handlebars" data-template-name="firstTab"> First Tab content </script> <script type="text/x-handlebars" data-template-name="secondTab"> Second Tab content </script> 

The code

 var App = Ember.Application.create(); App.ApplicationController = Ember.Controller.extend(); App.ApplicationView = Ember.View.extend(); App.FirstTabView = Ember.View.extend({templateName: "firstTab"}); App.FirstTabController = Ember.Controller.extend(); App.SecondTabView = Ember.View.extend({templateName: "secondTab"}); App.SecondTabController = Ember.Controller.extend(); App.Router = Ember.Router.create({ root: Ember.Route.extend({ goToFirstTab: Ember.Route.transitionTo("firstTab"), goToSecondTab: Ember.Route.transitionTo("secondTab"), index: Ember.Route.extend({ route: "/", redirectsTo: "firstTab" }), firstTab: Ember.Route.extend({ route: "/firstTab", connectOutlets: function (router) { router.get('applicationController').connectOutlet('firstTab'); } }), secondTab: Ember.Route.extend({ route: "/secondTab", connectOutlets: function (router) { router.get('applicationController').connectOutlet('secondTab'); } }) }) }); App.initialize(App.Router); 

The second way, without a router.

Templates (note that action goals have changed)

 <script type="text/x-handlebars" data-template-name="application"> <div class="tabpanel"> <div class="tabs"> <div {{action "goToFirstTab" target="controller"}}>First tab</div> <div {{action "goToSecondTab" target="controller"}}>Second tab</div> </div> {{outlet}} </div> </script> <script type="text/x-handlebars" data-template-name="firstTab"> First Tab content </script> <script type="text/x-handlebars" data-template-name="secondTab"> Second Tab content </script> 

The code (almost the same, except that the code associated with the tabs is now moved to the ApplicationController.

 var App = Ember.Application.create(); App.ApplicationView = Ember.View.extend(); App.Router = Ember.Route.create(); App.FirstTabView = Ember.View.extend({templateName: "firstTab"}); App.FirstTabController = Ember.Controller.extend(); App.SecondTabView = Ember.View.extend({templateName: "secondTab"}); App.SecondTabController = Ember.Controller.extend(); App.ApplicationController = Ember.Controller.extend({ view: App.FirstTabView.create(), goToFirstTab: function () { this.connectOutlet("firstTab"); }, goToSecondTab: function () { this.connectOutlet("secondTab"); } }); App.initialize(App.Router); 
0
source

All Articles