Dojo 1.7:BorderContainer 和 ContentPanes 无法在自定义小部件模板内工作
所以我有两个例子。第一个是声明性地使用 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>
This is similar to a question already on here but I'm using Dojo 1.7. So, I can't get BorderContainer and ContentPanes working inside of a custom widget template. It's driving me mad. I tried adding the mixins suggested in the other post and it didn't work.
So I have two examples. The first is a single page using dojo declaratively and it works fine. The second example is exactly the same page but I use a widget to embed the template. It renders the widgets but they are all stuck together in the top right corner. Same page, same styles. BUT, when i resize the browser window the page takes shape. There are still bits missing but it's better
screenshot here for second example after resizing the browser
window. Still not the same as the first example but better.
Many thanks
This is the first example, which works
<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>
And this is second example using a widget
<!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>
This is the widget code
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);
}
});
});
This is the template for the widget
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您可能需要在自己的
startup()
方法中显式调用 BorderContainer 和 ContentPane 布局小部件的启动。此外,如果您要重写和继承方法,您可能希望在任何小部件生命周期方法中始终拥有this.inherited(arguments)
。另外,正如 @missingno 提到的,您可能不希望清空
并在小部件启动期间替换它,作为一般可重用性的事情。
You might need to explicitly call startup on the BorderContainer and ContentPane layout widgets in your own
startup()
method. Also you probably want to always havethis.inherited(arguments)
in any of the widget lifecycle methods if you are overriding and inheriting method.Also, as @missingno mentioned, you probably don't want to be emptying the
<body>
and replacing it during widget startup, as a general reusability thing.我在其中的自定义 Widget 和 BorderContainers 中遇到了非常类似的问题,在我继承了 BorderContainer 而不是 BaseWidget 或 _Widget 后,它终于起作用了。
希望这对您的情况也有帮助!
I had a very similar problem with a custom Widget and BorderContainers within and it finally worked after I inherited BorderContainer instead BaseWidget or _Widget.
Hope that also helps in your case!
我正在创建模板化的自定义小部件,其中包含带有周围
div
的 BorderContainers(因为我无法让顶级 BorderContainer 工作),如下所示:我遇到了完全相同的布局问题(BorderContainer 仅在页面调整大小后才能正确布局),直到我意识到(感谢 John 的回答) Brinnand 上面)我需要将任何
resize
调用从 dijit 转发到“内部”BorderContainer。所以我所做的是在我的小部件中实现一个resize
方法("bc"
是 BorderContainer 小部件,通过data-dojo-attach-point< 引入/code> 如上面的代码所示):
你瞧:一切正常。
(我使用的是 dojo 1.9,但这应该适用于 dojo >= 1.7)
I'm creating my templated custom widgets which contain BorderContainers with a surrounding
div
(because I couldn't get a top-level BorderContainer to work), like so:I had the exact same layout problems (BorderContainer would only layout correctly after page resize), until I realized (thanks to the answer by John Brinnand above) that I need to forward any
resize
calls from dijit to the "inner" BorderContainer. So what I did was to implement aresize
method in my widget ("bc"
is the BorderContainer widget, brought in viadata-dojo-attach-point
as seen in the above code):and lo and behold: everything works fine.
(I'm using dojo 1.9, but this should work for dojo >= 1.7)
BorderContainer 是一个需要动态调整大小的布局小部件。您已经覆盖了启动方法,我敢打赌这至少是问题之一。
由于您的启动方法内容并不是真正的启动,我建议您尝试删除或重命名它(以公开原始启动)。
编辑(对于新问题):
我发现
很可疑,因为所有调整大小都是在实际放置小部件之前在 this.inherited 部分中完成的(因此调整大小最初不起作用
)可以尝试在这里切换顺序,但我认为最好完全删除启动方法并将 main 更改为
BorderContainer is a layout widget that needs to be dinamically sized. You have overwritten the startup method and I'd bet this is at least one of the problems.
Since your startup method contents aren't really startupy, I'd suggest you just try removing or renaming it (to expose the original startup).
Edit (for the new problem):
I find
to be suspicious, since all the resizing is done in the this.inherited part before the widget is actually placed (so the resizing doesn't work initially)
You could try switching the order here but I think it is better to just remove the startup method entirely and change the main to
创建布局的方法不是使用模板化小部件,而是以编程方式进行。我实际上并没有在任何地方找到这个,但我也找不到任何人引导我这样做;
The way to create layout is not using templated widgets but to do it programatically. I didn't actually find this anywhere but I also couldn't find anyone who was which lead me to doing it like this;
dojo 1.7 中小部件的构造和布局发生了变化。有一个固有的顺序:构造一个小部件,将其添加到其父级,启动,调整大小。在 1.7 之前,启动小部件的操作顺序是不同的。
在您的示例中:
相同的顺序将适用于边框容器的子级:
启动一个已经启动的容器似乎是多余的。你可以通过这个序列来找出什么是必要的,什么是不必要的。然而,resize() 是至关重要的。如果没有它,布局的大小将不正确并且不会渲染。
注意:此示例意味着 dojo 小部件的编程构建和连接。
The construction and layout of widgets has changed in dojo 1.7. There is an inherent order which is this: construct a widget, add it to it's parent, startup, resize. Prior to 1.7 the sequence of actions for starting a widget was different.
In your example:
The same sequence will apply to children of the border container:
It may seem redundant to start a container that has already started. And you can play with this sequence to find what is or is not necessary. However, the resize() is critical. Without it the layout is not sized correctly and will not render.
Note: this example implies programmatic construction and wire-up of dojo widgets.
将 BorderContainer 而不是 _Widget 子类化为 skython 的建议 似乎解决了大多数问题。仍然存在一些小问题,例如最初绘制小部件时未绘制一些边框,因此我通过
startup()
方法在子小部件上调用了resize()
。请注意,立即从启动方法调用 resize 不起作用,但使用 0 延迟的 setTimeout() 可以:Subclassing BorderContainer instead of _Widget as suggested by skython seemed to fix most issues. A few glitches remained like some borders not being drawn when initially drawing the widget, so I called
resize()
on the child widgets from thestartup()
method. Note immediately calling resize from the startup method does not work, but usingsetTimeout()
with 0 delay works:我奋斗了 4 个小时才最终让它以声明式和程序化的方式工作。关键是你必须在 dom 元素就位(可见?)之后调用 yourBorderContainerObj.startup() 或 .resize() 。
我试图创建一个模板化的小部件,其中包含一个 BorderContainer 和一些 ContentPanes,并将其放置在一个对话框中。首先,当对话框显示时,我无法让 BorderContainer 和 ContentPanes 正确显示,它们已初始化并分配了正确的类名,但 css 效果似乎没有应用。
我通过在小部件中执行以下操作来使模板化小部件正常工作:
就是这样。然后 BorderContainer 和 ContentPanes 都会正常工作。
顺便说一句,我正在使用 1.8.3。
I struggled 4 hrs to finally get it to work with both declarative and programmatic ways. The key is that you have to call the yourBorderContainerObj.startup() or .resize() after its dom element is in place(visible?).
I was trying to create a templated widget which contains a BorderContainer and a few ContentPanes, and placing it in a Dialog. First I couldn't get the BorderContainer and ContentPanes to show properly when the dialog shows, they were initialized and assigned correct class names, but the css effects weren't seem to be applied.
I get the templated widget to work by doing this in the widget:
That is it. Then the BorderContainer and the ContentPanes all work as they should.
BTW, I'm using 1.8.3.