1

我想问变量 instd: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现在的问题是,为什么无论用户单击a different ,都将相同的对象传递给方法span

我也怀疑这是因为id="collapse-primitive"这里导致了这种奇怪的行为。但是,我不知道如何在没有和 id 的情况下对其进行测试,因为我不知道如何在 Flavour 中执行此操作,这意味着当单击按钮时如何在代码中注入跨度,只有“隐藏”的 id它或用CSS“显示”它。好吧,这是另一个问题。

所以我的问题总结如下:

  1. 为什么std:foreach在事件中的每个函数中传递相同的(第一个)变量:async-click
  2. 您如何在按钮单击时为此注入 span 或任何 div 元素,或者 Flavour 这样做的方式是什么?
4

1 回答 1

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

element如果可以在 DOM 中的任何位置进行渲染,则此处的 HTML是可选的,如果是这种情况,则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);
    }
}

表单.html

<std:foreach var="property" in="properties">
  <button event:click="e -> showDropdown(e)"/>
</std:foreach>
于 2020-11-13T19:57:30.393 回答