这类似于已经在这里的question,但我正在使用Dojo 1.7。所以,我不能让BorderContainer和ContentPanes在自定义小部件模板中工作。这让我很生气。我尝试添加其他帖子中建议的mixins,但它没有用。
所以我有两个例子。第一个是以声明方式使用dojo的单个页面,它工作正常。第二个例子是完全相同的页面,但我使用一个小部件来嵌入模板。它呈现小部件,但它们都在右上角粘在一起。相同的页面,相同的样式。但是,当我调整浏览器窗口的大小时,页面就会成形。仍然有一些缺失,但它更好
非常感谢
这是第一个有效的例子
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Application Controller</title>
<link rel="stylesheet" href="/js/tag/widgets/BorderWidget/css/demo.css" media="screen">
<link rel="stylesheet" href="/js/tag/widgets/BorderWidget/css/style.css" media="screen">
<link rel="stylesheet" href="/js/dijit/themes/claro/claro.css" media="screen">
<!-- Configure Dojo -->
<script type="text/javascript">
var djConfig = {
isDebug : true,
parseOnLoad : true
};
</script>
<script type="text/javascript" src="/js/dojo/dojo.js"></script>
<script>
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.layout.ContentPane");
</script>
</head>
<body class="claro">
<div style="height:100%">
<div id="appLayout" class="demoLayout" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design: 'headline'">
<div class="centerPanel" id="tabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props="region: 'center', tabPosition: 'bottom'">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title: 'About'">
<h2>Flickr keyword photo search</h2>
<p>
Each search creates a new tab with the results as thumbnails
</p>
<p>
Click on any thumbnail to view the larger image
</p>
</div>
</div>
<div class="edgePanel" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
<div class="searchInputColumn">
<div class="searchInputColumnInner">
<input id="searchTerms" placeholder="search terms">
</div>
</div>
<div class="searchButtonColumn">
<button id="searchBtn">
Search
</button>
</div>
</div>
</div>
</div>
</body>
</html>
这是使用小部件的第二个例子
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Application Controller</title>
<link rel="stylesheet" href="/js/tag/widgets/BorderWidget/css/demo.css" media="screen">
<link rel="stylesheet" href="/js/tag/widgets/BorderWidget/css/style.css" media="screen">
<link rel="stylesheet" href="/js/dijit/themes/claro/claro.css" media="screen">
<!-- Configure Dojo -->
<script type="text/javascript">
var djConfig = {
isDebug : true,
parseOnLoad : true,
paths : {
'tag' : '../tag/widgets/BorderWidget'
}
};
</script>
<script type="text/javascript" src="/js/dojo/dojo.js"></script>
<script>
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require('tag.Widget');
dojo.ready(function() {
new tag.Widget().startup();
});
</script>
</head>
<body class="claro">
</body>
</html>
这是小部件代码
define('tag/Widget',
[
'dojo',
'dijit/_Widget',
'dijit/_TemplatedMixin',
'dijit/_WidgetsInTemplateMixin',
'dijit/layout/BorderContainer',
'dijit/layout/TabContainer',
'dijit/layout/ContentPane'
],
function(d) {
//The widget contructor will be returned
return d.declare('tag.Widget',
[
dijit._Widget,
dijit._TemplatedMixin,
dijit._WidgetsInTemplateMixin
],
{
templateString : d.cache("tag", "templates/template.html"),
postCreate : function() {
this.inherited(arguments);
var domNode = this.domNode;
},
startup : function(args) {
this.inherited(arguments);
this.placeAt(dojo.doc.body);
}
});
});
这是小部件的模板
<div style="height:100%">
<div id="appLayout" class="demoLayout" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design: 'headline'">
<div class="centerPanel" id="tabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props="region: 'center', tabPosition: 'bottom'">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title: 'About'">
<h2>Flickr keyword photo search</h2>
<p>
Each search creates a new tab with the results as thumbnails
</p>
<p>
Click on any thumbnail to view the larger image
</p>
</div>
</div>
<div class="edgePanel" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
<div class="searchInputColumn">
<div class="searchInputColumnInner">
<input id="searchTerms" placeholder="search terms">
</div>
</div>
<div class="searchButtonColumn">
<button id="searchBtn">
Search
</button>
</div>
</div>
</div>
</div>
答案 0 :(得分:4)
您可能需要在自己的startup()
方法中显式调用BorderContainer和ContentPane布局小部件上的启动。如果要覆盖和继承方法,您可能希望在任何窗口小部件生命周期方法中始终具有this.inherited(arguments)
。
startup : function(args) {
this.inherited(arguments);
//console.log('asdasd')
dojo.empty("body");
this.placeAt('body');
this.subContainerWidget.startup();
//I think the border container will automatically call startup on its children
//(the content panes), but you may also need to call startup on them.
}
另外,正如@missingno所提到的,你可能不希望清空<body>
并在小部件启动期间替换它,作为一般的可重用性。
答案 1 :(得分:4)
我在自定义Widget和BorderContainers中遇到了一个非常类似的问题,它在我继承BorderContainer而不是BaseWidget或_Widget后终于工作了。 希望这也有助于您的情况!
答案 2 :(得分:2)
我正在创建我的模板化自定义小部件,其中包含带有周围div
的BorderContainer(因为我无法使顶层BorderContainer工作),如下所示:
<div style="height: 100%;">
<div style="height: 100%;" data-dojo-type="dijit/layout/BorderContainer"
data-dojo-attach-point="bc"
data-dojo-props="design: 'headline', gutters: false">
<div data-dojo-type="dijit/layout/ContentPane"
data-dojo-props="region: 'top'">
</div>
<div data-dojo-type="dijit/layout/ContentPane"
data-dojo-props="region: 'center'">
</div>
</div>
我有完全相同的布局问题(BorderContainer只会在页面调整大小后才能正确布局),直到我意识到(感谢上面John Brinnand的答案)我需要转发任何resize
来自dijit到“内部”BorderContainer。所以我所做的是在我的小部件中实现resize
方法("bc"
是BorderContainer小部件,通过data-dojo-attach-point
引入,如上面的代码所示):
resize: function () {
this.bc.resize(arguments);
this.inherited(arguments);
}
瞧瞧:一切正常。
(我正在使用dojo 1.9,但这应该适用于dojo&gt; = 1.7)
答案 3 :(得分:1)
BorderContainer是一个需要大小调整的布局小部件。你已经覆盖了启动方法,我敢打赌这至少是其中一个问题。
由于您的启动方法内容并非真正启动,我建议您尝试删除或重命名它(以显示原始启动)。
d.declare(...)|{
...
toFullScreen: function(){
dojo.empty("body");
this.placeAt('body');
}
}
var w = new FlickApiView({...});
w.toFullScreen();
w.startup();
修改(针对新问题):
我找到了
startup : function(args) {
this.inherited(arguments);
this.placeAt(dojo.doc.body);
}
要怀疑,因为所有调整大小都是在实际放置小部件之前在this.inherited部分完成的(因此调整大小最初不起作用)
您可以尝试在此处切换订单,但我认为最好完全删除启动方法并将主要内容更改为
var w = new tags.Widget();
w.placeAt(dojo.body());
s.startup();
答案 4 :(得分:1)
创建布局的方法不是使用模板化小部件,而是以编程方式执行。我实际上并没有在任何地方找到这个,但我也找不到任何导致我这样做的人;
// view
define('tag/views/CampaignTest/layout', [
'dojo',
'dbp/widgetStore',
'dijit/layout/BorderContainer',
'dijit/layout/TabContainer',
'dijit/layout/ContentPane',
'dojo/NodeList-manipulate'
],
function(dojo, widgetStore, BorderContainer, TabContainer, ContentPane) {
return {
create : function (layoutName) {
var deferred = new dojo.Deferred(),
add = dojo.partial(widgetStore.add, layoutName);
dojo.query("body").prepend("<div id='appLayout' class='demoLayout'></div>");
var appLayout = add(
new BorderContainer({
design: "headline"
}, dojo.byId("appLayout"))
);
// create the TabContainer
var contentTabs = add(
new dijit.layout.TabContainer({
region: "center",
id: "contentTabs",
tabPosition: "bottom",
"class": "centerPanel",
href: "contentCenter.html"
})
);
// add the TabContainer as a child of the BorderContainer
appLayout.addChild( contentTabs );
// create and add the BorderContainer edge regions
appLayout.addChild(
add(
new dijit.layout.ContentPane({
style : "height:50px",
region: "top",
id : "top",
"class": "edgePanel",
content: "Header content (top)"
})
)
);
appLayout.addChild(
add(
new dijit.layout.ContentPane({
style : "height:50px",
region: "top",
id : "top2",
"class": "edgePanel",
content: "Next content (top)"
})
)
);
appLayout.addChild(
add(
new dijit.layout.ContentPane({
region: "left",
id: "leftCol",
"class": "edgePanel",
content: "Sidebar content (left)",
splitter: true
})
)
);
contentTabs.addChild(
add(
new dijit.layout.ContentPane({
title: "Start"
}, dojo.byId("startContent"))
)
);
// not even sure this is necessary but I
// check to make sure layout has finished
(function check(){
setTimeout(function(){
appLayout.domNode ? deferred.resolve() : check();
}, 10);
})();
appLayout.startup();
return deferred;
}
};
});
答案 5 :(得分:1)
在dojo 1.7中,小部件的构造和布局发生了变化。这有一个固有的顺序:构建一个小部件,将其添加到它的父级,启动,调整大小。在1.7之前,启动小部件的操作顺序是不同的。
在你的例子中:
相同的序列将适用于边框容器的子项:
启动已启动的容器似乎有点多余。您可以使用此序列来查找有用或不必要的内容。但是,resize()是至关重要的。没有它,布局的大小不正确,也不会渲染。
注意:此示例意味着dojo小部件的编程构造和连接。
答案 6 :(得分:0)
将BorderContainer而不是_Widget子类化为suggested by skython似乎解决了大多数问题。在最初绘制窗口小部件时,有些边缘仍然没有被绘制,所以我在resize()
方法的子窗口小部件上调用了startup()
。请注意,立即从启动方法调用resize不起作用,但使用setTimeout()
0延迟工作:
startup : function(args) {
// Hack to force widget to initially draw properly.
array.forEach(this.getChildren(), function(elem, id) {
setTimeout(elem.resize, 0);
});
this.inherited(arguments);
},
答案 7 :(得分:0)
我挣扎了4个小时,最终让它以声明式和编程式方式工作。关键是你必须在其dom元素就位(可见?)之后调用yourBorderContainerObj.startup()或.resize()。
我试图创建一个模板化的小部件,其中包含BorderContainer和一些ContentPanes,并将其放在Dialog中。首先,当对话框显示时,我无法正确显示BorderContainer和ContentPanes,它们已被初始化并分配了正确的类名,但css效果似乎并未应用。
我通过在小部件中执行此操作来使模板化小部件工作:
resize: function() {
this.inherited(arguments);
this.myBorderContainerObj.resize();
}
就是这样。然后BorderContainer和ContentPanes都可以正常工作。
BTW,我使用的是1.8.3。