在 foreach 循环中将变量传递给函数
Passing a variable to a function in a foreach loop
请问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
跨度中的方法应该不同。请原谅我的解释不够充分,但代码本身是不言自明的。
现在的问题是,为什么无论用户在不同的 span
中单击 li
,都会将相同的对象传递给该方法?
我还怀疑是因为这里的 id="collapse-primitive"
导致了这种奇怪的行为。但是,我不知道如何在没有 id 的情况下测试它,因为我不知道如何在 Flavour 中执行此操作,这意味着如何在单击按钮时在代码中注入 span,id 只是“隐藏”它或用 CSS“显示”它。好的,这是另一个问题。
所以我的问题总结如下:
- 为什么 std:foreach 在每个函数中传递相同的(第一个)变量
event:async-点击
- 你如何为这件事注入跨度或任何 div 元素
甚至单击按钮或者 Flavour 的做法是什么?
对此的解决方案是创建类似 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);
}
这里的HTMLelement
是可选的,如果渲染可以在DOM的任何地方完成,如果是这样的话,DOM里面的典型注入Dropdown.show()
方法可以实现:
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>
请问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
跨度中的方法应该不同。请原谅我的解释不够充分,但代码本身是不言自明的。
现在的问题是,为什么无论用户在不同的 span
中单击 li
,都会将相同的对象传递给该方法?
我还怀疑是因为这里的 id="collapse-primitive"
导致了这种奇怪的行为。但是,我不知道如何在没有 id 的情况下测试它,因为我不知道如何在 Flavour 中执行此操作,这意味着如何在单击按钮时在代码中注入 span,id 只是“隐藏”它或用 CSS“显示”它。好的,这是另一个问题。
所以我的问题总结如下:
- 为什么 std:foreach 在每个函数中传递相同的(第一个)变量 event:async-点击
- 你如何为这件事注入跨度或任何 div 元素 甚至单击按钮或者 Flavour 的做法是什么?
对此的解决方案是创建类似 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);
}
这里的HTMLelement
是可选的,如果渲染可以在DOM的任何地方完成,如果是这样的话,DOM里面的典型注入Dropdown.show()
方法可以实现:
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>