我是新手,并试图构建一个Ember驱动的Web应用程序。我已经阅读了各种各样的内容并研究了几个例子。基本概念很清楚,但现在我仍然试图实现一个tabpanel。我的方法如下:
查看
Configurator.TabPanelView = Ember.View.extend({
classNames: ['tabPanel'],
templateName: 'tabPanel'
});
模板
<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>
在App中使用
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正确呈现但如果我尝试点击后面出现错误的li元素
未捕获错误:断言失败:目标&lt;(子类的 Ember.View):ember217&GT;没有行动{{this.actionName}}
我也很好奇我是否应该使用路由器来实现标签。但据我所知,路由器可以在应用程序级别上运行,并且可以在单个UI组合中使用。
答案 0 :(得分:2)
问题在于您的模板:
<li {{action "{{this.actionName}}" target="{{this.value}}"}} >{{this.title}}</li>
AFAIK,操作无法绑定,因此当您编写此操作时,它会尝试调用方法{{this.actionName}}
而不是firstTab
,例如。
我认为这是一个典型的例子,您应该使用Ember.CollectionView itemViewClass
click
方法,即:{/ p>
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);
}
})
});
上面的代码肯定不对,但这个想法就在这里。
但我认为路由器是正确的方法。我建议您查看Ember Router example by @ghempton,其中Ember.Router
定义标签。
答案 1 :(得分:1)
您有两个选择:
1)每个标签页都有自己的控制器,视图,也必须在路由器中定义
<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)所有标签页都在一个大视图中,并且将隐藏或显示标签页
{{#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()
});
答案 2 :(得分:0)
有两种方法可以实现选项卡面板。
如果您希望您的标签可以添加书签,那么您应该使用路由器实现它们:
<强>模板强>
<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>
<强>代码强>:
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);
第二种方式,没有路由器。
模板(请注意,操作目标已更改)
<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>
代码(几乎相同,只是与标签相关的代码现在已移至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);