想象一下以下情况。我有一个绝对定位的侧边栏,然后在侧边栏中放置了一些更多的东西。在该侧边栏中,我有一个显示菜单的按钮,模板如下所示:
<button>Click me</button>
{{#if shouldDisplayMenu}}
{{view App.MyMenu}}
{{/if}}
我喜欢这个解决方案并希望保留的是模板中的菜单定义在按钮旁边,这样可以保持良好的可维护性。
问题在于我希望菜单相对于视口定位,即渲染到document.body并使用绝对位置定位。这样它将呈现到侧边栏并导致滚动条可见,因为我已经通过其中一个父元素中的位置相对重置了定位上下文。
我有什么方法可以保持{{view App.MyMenu}}现在的位置,但让它渲染到身体(可能使用插座或其他机制)?这种情况的推荐模式是什么?
答案 0 :(得分:12)
有很多方法可以在ember
中使用相关上下文呈现视图。我提出了四种方法(我认为第一种方法更有可能是你想要的):
1. 如果视图需要放置在手柄模板之外的某个位置,则可以使用jQuery将呈现的内容放置在需要的位置。
(因为视图元素的替换发生在didInsertElement
之后,可能还需要添加样式以不显示元素,例如display:none
,并在重新定位后显示它)
示例强> http://emberjs.jsbin.com/gotabore/1/edit
2。如果该地点位于另一个模板中的某个位置,请使用{{render}}
帮助器将视图渲染到位。虽然我不确定上下文要求,但这个助手非常灵活(http://emberjs.com/guides/templates/rendering-with-helpers/#toc_the-code-render-code-helper)。
示例强> http://emberjs.jsbin.com/xibayava/1/edit
3。使用{{outlet}}
帮助程序根据访问route
中指定的内容呈现视图。 (http://emberjs.com/guides/routing/rendering-a-template/)
示例强> http://emberjs.jsbin.com/tiyuqenu/1/edit
4. 使用ContainerView
以编程方式将视图推送到需要的位置。
示例强> http://emberjs.jsbin.com/yoyujeqi/1/edit
方法4的更新: 对于等于或大于1.8.x的版本,为了避免http://emberjs.com/guides/deprecations/#toc_global-lookup-of-views中提到的错误,可以指定与之关联的属性ContainerView
,如以下示例所示
http://emberjs.jsbin.com/difayakeki/1/edit?html,js,output
相关代码
接近1
<强> HBS 强>
<script type="text/x-handlebars">
<h2> Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
This is index<br/>
{{view App.TestView}}
</script>
<script type="text/x-handlebars" data-template-name="test">
This is the test view<br/>
<b>{{myProp}}</b>
</script>
<div id="a-div" style="background-color:lightgray">
This is a div somewhere,<br/>
</div>
<强> JS 强>
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexController = Ember.Controller.extend({
myProp:"index controller prop"
});
App.IndexView = Ember.View.extend({
placeTestViewSomewhere:function(){
var theTestView = this.$(".my-test-view").detach();
$("#a-div").append(theTestView);
}.on("didInsertElement")
});
App.TestView = Ember.View.extend({
templateName:"test",
classNames:["my-test-view"]
});
接近2
<强> HBS 强>
<script type="text/x-handlebars">
<h2> Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
This is index<br/>
<div style="background-color:lightgray">
This is a div in index template with render helper,<br/>
{{render "test"}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="test">
This is the test view<br/>
<b>{{myProp}}</b>
</script>
<强> JS 强>
App.IndexView = Ember.View.extend({
placeTestViewSomewhere:function(){
// var theTestView = this.$(".my-test-view").detach();
// $("#a-div").append(theTestView);
}.on("didInsertElement")
});
App.TestController = Ember.Controller.extend({
myProp:"test controller prop"
});
App.TestView = Ember.View.extend({
templateName:"test"
});
接近3
<强> HBS 强>
<script type="text/x-handlebars">
<h2> Welcome to Ember.js</h2>
{{outlet}}
<div style="background-color:lightgray">
This is a div in application template with outlet helper,<br/>
{{outlet "test-outlet"}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="index">
This is index<br/>
</script>
<script type="text/x-handlebars" data-template-name="test">
This is the test view<br/>
<b>{{myProp}}</b>
</script>
<强> JS 强>
App.IndexRoute = Ember.Route.extend({
renderTemplate: function() {
this.render("index");
this.render('test', { // the template to render
into: 'application', // the template to render into
outlet: 'test-outlet' // the name of the outlet in that template
});
}
});
App.IndexView = Ember.View.extend({
placeTestViewSomewhere:function(){
// var theTestView = this.$(".my-test-view").detach();
// $("#a-div").append(theTestView);
}.on("didInsertElement")
});
App.TestController = Ember.Controller.extend({
myProp:"test controller prop"
});
App.TestView = Ember.View.extend({
templateName:"test"
});
接近4
<强> HBS 强>
<script type="text/x-handlebars">
<h2> Welcome to Ember.js</h2>
{{outlet}}
<div style="background-color:lightgray">
This is a div in application template with view helper and a view container,<br/>
{{view Ember.ContainerView viewName="my-menu-container"}}
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="index">
This is index<br/>
</script>
<script type="text/x-handlebars" data-template-name="test">
This is the test view<br/>
<b>{{myProp}}</b>
</script>
<强> JS 强>
App.IndexController = Ember.Controller.extend({
myProp:"index controller prop"
});
App.IndexView = Ember.View.extend({
placeTestViewSomewhere:function(){
var theTestView = App.TestView.create({});
theTestView.set("context",this.get("context"));
this.get("parentView.my-menu-container").pushObject(theTestView);
}.on("didInsertElement")
});
App.TestView = Ember.View.extend({
templateName:"test"
});
方法4的更新:
<强> JS 强>
App.ApplicationView = Em.View.extend({
containerView:Em.ContainerView
});
<强> HBS 强>
{{view view.containerView viewName="my-menu-container"}}