我想问一下std:foreach
中的变量是如何处理的?
我有这样一种情况,即同一个对象传递给一个函数,无论它不是应该传递的那个对象:
<std:foreach var="property" in="properties">
<button onclick="unhide('collapse-primitive')"/>
<span class="hidden" id="collapse-primitive">
<ul class="">
<li event:async-click="setItemPropertyType(property, 'String')">String</li>
<li event:async-click="setItemPropertyType(property, 'Boolean')">Boolean</li>
<li event:async-click="setItemPropertyType(property, 'Integer')">Integer</li>
<li event:async-click="setItemPropertyType(property, 'Long')">Long</li>
<li event:async-click="setItemPropertyType(property, 'Double')">Double</li>
<li event:async-click="setItemPropertyType(property, 'Set')">Set</li>
<li event:async-click="setItemPropertyType(property, 'List')">List</li>
<li event:async-click="setItemPropertyType(property, 'Map')">Map</li>
</ul>
</span>
</std:foreach>
上面的代码为属性列表中的每个项目生成一个跨度,问题是函数setItemPropertyType
总是获取第一个项目,而这是一个循环,因此意味着为每个setItemPropertyType
传递的对象跨度中的方法应该不同。如果我的解释还不够,请原谅,但是代码本身是不言自明的。
现在的问题是,无论用户单击其他li
中的span
,为什么将同一个对象传递给方法?
我还怀疑是由于id="collapse-primitive"
导致了这种奇怪的行为。但是,我不知道如何在没有和id的情况下进行测试,因为我不知道如何在Flavour中执行此操作,这意味着当单击按钮时,如何在代码中注入跨度,而id只是“隐藏”或使用CSS“显示”它。好的,这是另一个问题。
所以我的问题总结如下:
答案 0 :(得分:-1)
解决方案是创建类似于Dropdown组件的组件,该组件可以通过HTML包装器将自身呈现为DOM。
在TeaVM中,可以通过以下方法解决:
public interface DropdownContent {
void setDelegate(DropdownDelegate delegate);
}
此内容可以是任何HTML,并具体表示为:
@BindTemplate("templates/views/custom-dropdown-content.html")
public class CustomDropdownContent implements DropdownContent {
}
使用此HTML模板:
<span>
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
</ul>
</span>
显然,其他任何具体的实现都可以使用任何HTML模板完成。
现在,这仍然只是必须通过某种静态方法显示给DOM的内容,该方法可以帮助快速构建组件UI :
public void showDropdown(MouseEvent event) {
HTMLElement element = (HTMLElement) event.getTarget();
DropdownContent content = new CustomDropdownContent();
Dropdown.show(content, element);
}
如果可以在DOM中的任何位置进行渲染,则HTML element
是可选的,如果是这种情况,则可以在Dropdown.show()
方法内实现典型的DOM注入:
document.getBody().appendChild(dropdownComponent.wrapper);
dropdownComponent.component = Templates.bind(dropdownComponent, dropdownComponent.wrapper);
如果您要包装用户单击过的东西等组件,则不需要上面的代码。
现在,对于Dropdown本身,可以这样实现:
@BindElement(name = "dropdown")
@BindTemplate("templates/components/dropdown.html")
public class Dropdown {
private static HTMLDocument document = HTMLDocument.current();
private Fragment content;
private Component component;
private HTMLElement wrapper;
public Dropdown(Fragment content) {
this.content = content;
}
public Fragment getContent() {
return content;
}
public void setContent(Fragment content) {
this.content = content;
}
public static void show(DropdownContent content, HTMLElement wrapper) {
Dropdown dropdown = new Dropdown(Templates.create(content));
dropdown.wrapper = wrapper;
dropdown.component = Templates.bind(dropdown, dropdown.wrapper);
}
}
使用非常简单的HTML模板:
<div>
<std:insert fragment="content"/>
</div>
最后,可以在小部件中使用它,例如:
@BindElement(name = "simple-form")
@BindTemplate("templates/components/form.html")
public class FormComponent extends AbstractWidget {
public void showDropdown(MouseEvent event) {
HTMLElement element = (HTMLElement) event.getTarget();
DropdownContent content = new CustomDropdownContent();
Dropdown.show(content, element);
}
}
form.html
<std:foreach var="property" in="properties">
<button event:click="e -> showDropdown(e)"/>
</std:foreach>