有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将变量传递给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>

上面的代码为属性列表中的每个项生成一个span,问题是函数setItemPropertyType总是获取第一个项,而这是一个循环,这意味着span中每个setItemPropertyType方法传递的对象应该不同。如果我的解释不充分,请原谅,但代码本身是不言自明的

现在的问题是,为什么不管用户在不同的span中单击li,都会将相同的对象传递给该方法

我还怀疑这是因为这里的id="collapse-primitive"导致了这种奇怪的行为。然而,我不知道如何在没有和id的情况下测试它,因为我不知道如何在Flavor中这样做,这意味着当点击按钮时,如何在代码中注入跨度,有id可以用CSS“隐藏”它或“显示”它。好吧,这是另一个问题

因此,我的问题总结如下:

  1. 为什么std:foreach在中的每个函数中传递相同的(第一个)变量 事件:异步单击
  2. 如何为这个问题注入span或任何div元素 甚至点击按钮,或者味道是怎么做的

共 (1) 个答案

  1. # 1 楼答案

    解决方案是创建一个类似下拉组件的东西,它可以通过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);
    

    如果您想从用户单击的内容等包装组件,则不需要上面的代码

    现在,对于下拉列表本身,它可以这样实现:

    @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);
        }
    }
    

    形式。html

    <std:foreach var="property" in="properties">
      <button event:click="e -> showDropdown(e)"/>
    </std:foreach>