1
我刚刚将CodeMirror(带有一些插件)作为JSF 2.0复合组件(请参阅下面的代码)实现。只要组件没有放置在某个标签或对话框中(只是在页面加载后不可见),该组件才能正常工作。在制表符或对话框中,看起来像组件被渲染,但内容和行号在组件被点击之前不可见。作为JSF 2.0复合组件的CodeMirror无法在选项卡或对话框中正确呈现
点击之前: 点击
后:
这里是我的JSF复合组件模板代码:
<!-- INTERFACE -->
<cc:interface>
<cc:attribute name="styleClass" type="java.lang.String" required="true" />
<cc:attribute name="value" type="java.lang.Object" />
<cc:attribute name="converter" type="java.lang.String" />
<cc:attribute name="mode" type="java.lang.String" />
<cc:attribute name="theme" type="java.lang.String" default="eclipse" />
<cc:attribute name="lineNumbers" type="java.lang.String" default="false" />
<cc:attribute name="matchBrackets" type="java.lang.String" default="false" />
<cc:attribute name="matchTags" type="java.lang.String" default="false" />
<cc:attribute name="closeBrackets" type="java.lang.String" default="false" />
<cc:attribute name="closeTag" type="java.lang.String" default="false" />
<cc:attribute name="activeLine" type="java.lang.String" default="false" />
<cc:attribute name="indentUnit" type="java.lang.Integer" default="2" />
<cc:attribute name="smartIndent" type="java.lang.Boolean" default="true" />
<cc:attribute name="readOnly" type="java.lang.Boolean" default="false" />
<cc:attribute name="electricChars" type="java.lang.Boolean" default="true" />
<cc:attribute name="lineWrapping" type="java.lang.Boolean" default="false" />
<cc:attribute name="firstLineNumber" type="java.lang.Integer" default="1" />
<cc:attribute name="tabIndex" type="java.lang.Integer" default="0" />
<cc:attribute name="undoDepth" type="java.lang.Integer" default="40" />
<cc:attribute name="pollInterval" type="java.lang.Integer" default="100" />
<cc:attribute name="extraKeys" type="java.lang.String" default="{}" />
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<!-- required imports -->
<h:inputTextarea id="cmTextArea" value="#{cc.attrs.value}"
styleClass="#{cc.attrs.styleClass}">
<c:if test="#{not empty cc.attrs.converter}">
<f:converter converterId="#{cc.attrs.converter}" />
</c:if>
</h:inputTextarea>
<script type="text/javascript">
$(function() {
var cmTextArea = $('.#{cc.attrs.styleClass}'),
myCodeMirror = CodeMirror.fromTextArea(cmTextArea[0], {
value: cmTextArea.val(),
mode: '#{cc.attrs.mode}',
theme: '#{cc.attrs.theme}',
lineNumbers: #{cc.attrs.lineNumbers},
matchBrackets: '#{cc.attrs.matchBrackets}',
matchTags: {bothTags: #{cc.attrs.matchTags}},
autoCloseBrackets: #{cc.attrs.closeBrackets},
autoCloseTags: #{cc.attrs.closeTag},
styleActiveLine: #{cc.attrs.activeLine},
indentUnit: #{cc.attrs.indentUnit},
smartIndent: #{cc.attrs.smartIndent},
readOnly: #{cc.attrs.readOnly},
electricChars: #{cc.attrs.electricChars},
lineWrapping: #{cc.attrs.lineWrapping},
firstLineNumber: #{cc.attrs.firstLineNumber},
tabindex: #{cc.attrs.tabIndex},
undoDepth: #{cc.attrs.undoDepth},
pollInterval: #{cc.attrs.pollInterval},
extraKeys: #{cc.attrs.extraKeys}
});
});
</script>
使用复合材料部件的例子:
<t:codeMirror mode="text/xml" theme="cobalt"
value="#{bean.content}" tabIndex="1" lineNumbers="true"
converter="escapeConverter" electricChars="true" lineWrapping="true"
extraKeys="{ 'F11': function(cm) {cm.setOption('fullScreen', !cm.getOption('fullScreen'));}, 'Ctrl-J': 'toMatchingTag','Ctrl-Space': 'autocomplete' }"
matchBrackets="true" closeBrackets="true" matchTags="true"
closeTag="true" styleClass="sampleClass" />
正如我所说,我不明白,为什么没有内容显示(立即)在我的组件(没有点击它),放在一个(第二 - 在页面加载不可见)选项卡,而组件,放置在Primefaces之外'tabView被正确渲染(带有内容和行号)。
任何帮助将不胜感激。谢谢!
编辑: 我想我需要调用refresh
时codemirror对象变得可见(上标签显示)。太好了,它可以这样工作,但是有什么办法可以将这个调用包含在复合组件中吗?
好吧,我添加了一个'refresh'调用时,第二个标签(p:tabView)变为活动(在标签显示),它的工作原理。问题是我必须在每次使用我的复合组件时再创建一个JS函数。有没有办法在组件实现中包含该调用? – peterremec
不幸的是,不,我们一直无法找到一种理智的方式来在给定的DOM元素变得可见时得到通知。 – Marijn
我猜我认为...无论如何,感谢您的帮助。现在,我将打开这个问题并将您的答案标记为有用。 – peterremec