简体   繁体   English

将自定义模板传递给模板组件

[英]Passing custom template to stencil component

I'm working on to create a custom component using Stencil to replicate UI-select .我正在使用 Stencil 创建自定义组件来复制UI-select

The component will be used like:该组件将被用作:

let items = [{name:"Abc", age: 10}, {name:"Xyz", age: 10}];
let itemString = JSON.stringify(items);

<dropdown-search placeholder="Select User" item-string='${itemString}'>
</dropdown-search>

Then the component is defined as然后组件定义为

import {
  Component,
  State,
  Prop,
  Element,
} from '@stencil/core';

@Component({
  tag: 'dropdown-search',
})
export class DropdownSearch {
  @Element() dropdownEl: HTMLElement;
  @State() isOpen: boolean = false;
  @State() items: any = [];
  @Prop() itemString: string = '';
  @Prop() placeholder: string = '';

  componentDidLoad() {
    try {
      this.items = JSON.parse(this.itemString);
    } catch(e) {}
  }

  onClickDropdownHandler = (e: UIEvent) => {
    e.preventDefault();
    this.toggleDropdown();
  }

  toggleDropdown = () => {
    this.isOpen = !this.isOpen;
    if (this.isOpen) {
      window.setTimeout(
        () => {
          this.dropdownEl.querySelector('input').focus();
        },
        0,
      );
    }
  }

  renderOptions = () => {
    if (!Array.isArray(this.items) || !this.items.length) {
      return null;
    }

    return this.items.map((item) => (
      <li
      >
        <a href="javascript:" title="{item.name}">
         {item.name}
         <small class="d-block">age: {item.age}</small>
        </a>
      </li>
   ));
 }

 render() {
   let dropdownClassName = (this.isOpen ? 'open' : '');
   return (
    <form name="myForm">
      <div class="form-group">
        <div
          class={`btn-group dropdown ${dropdownClassName}`}
        >
          <button
            class="btn btn-default dropdown-toggle"
            onClick={this.onClickDropdownHandler}
          >
            {this.placeholder}
          </button>
          <ul class="dropdown-menu" role="menu">
            <li>
              <div class="input-group input-group-search">
                <input
                  class="form-control"
                  type="search"
                />
              </div>
            </li>
            {this.renderOptions()}
          </ul>
        </div>
      </div>
    </form>
  );
 }
}

The items are rendering fine.物品呈现良好。 As as the user can pass a custom array of objects, so I need to customize the options template.由于用户可以传递自定义对象数组,因此我需要自定义选项模板。 So the user can pass it while using the component.所以用户可以在使用组件时传递它。

Right now I'm using a static template for the options within the component, like现在我正在为组件中的选项使用静态模板,例如

<a href="javascript:" title="{item.name}">
  {item.name}
  <small class="d-block">age: {item.age}</small>
</a>

but I need a way to pass this template from where I'm using the template.但我需要一种方法来从我使用模板的地方传递这个模板。 I can't use slot there as I'm using the same template within all the options that running in a loop.我不能在那里使用插槽,因为我在循环运行的所有选项中使用相同的模板。

I am new with stencil but just tried to utilize an @Prop function for this, and it worked:我是模板的新手,但只是尝试为此使用 @Prop 函数,它起作用了:

Component成分

@Component({
  tag: 'dropdown-search',
  styleUrl: 'dropdown-search.css',
  shadow: true,
})
export class DropdownSearch {
  // allow template function to be passed from outside
  @Prop template!: (item: SelectItem) => any;
  @State items!: SelectItem[] = [{name: 'dog'}, {name: 'cat'}, {name: 'elephant'}];

  render() {
    return (
      <Host>
        <p>Before Template</p>
        {/* render the custom template here: */}
        {this.items.map(item => this.template(item))}
        <p>After Template</p>
      </Host>
    );
  }
}

Providing custom template to this component:为该组件提供自定义模板:

class AppComponent {
  render() {
    // Here we define our custom template to be rendered in MyComponent
    const CustomTemplate = (item: SelectItem) => <p key={item.name}>Hi, I am {item.name}</p>;

    return (
      <div class="app-home">
        <dropdown-search template={CustomTemplate} />
      </div>
    );
  }
}

result looks like this:结果如下所示:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM