代码之家  ›  专栏  ›  技术社区  ›  Josh Kelley

惯用角形构件

  •  3
  • Josh Kelley  · 技术社区  · 6 年前

    我正在创建一个表单,它使用引导输入组允许用户输入百分比。

    <div class="input-group">
      <input type="number" class="form-control" step="0.01">
      <div class="input-group-append">
        <span class="input-group-text">%</span>
      </div>
    </div>
    

    没什么特别的,但有点冗长,我可能想在以后添加或修改我处理百分比输入的方式,所以我不想对表单上的每个百分比字段重复这个HTML块。如果我在做React,我会把它封装在一个简单的功能组件中,然后就可以完成了。

    const PercentInput = props => (
      <div class="input-group">
        <input {...props} type="number" step="0.01">
        <div class="input-group-append">
          <span class="input-group-text">%</span>
        </div>
      </div>
    );
    

    现在我有一个 PercentInput 这就像 input (除了一个不同的DOM)而且这不需要知道或关心它是如何使用的,因为它可以盲目地将任何和所有道具传递给 输入 它包装和模拟的节点。

    在Angular中创建等效组件似乎要复杂得多。据我所知,我必须做到以下几点:

    这看起来太复杂了,这让我觉得我陷入了一种反应心态,我不知道或者误解了一个惯用的角度应用程序是如何做到这一点的。

    用一种典型的、干净的、惯用的角度来处理这个问题的方法是什么?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Michael Kang    6 年前

    创建具有输入属性字典的组件:

    输入百分比。组成部分ts

    import { 
        Component, ViewChild, ElementRef, AfterViewInit, Input 
    } from '@angular/core';
    
    @Component({
        selector: 'percent-input',
        templateUrl: 'percent-input.component.html'
    })
    export class PercentInputComponent implements AfterViewInit {
        @ViewChild('inputField') inputField: ElementRef;
        @Input() props: { [key: string]: string };
        constructor() { }
    
        ngAfterViewInit() {
            if (this.props) {
                Object.keys(this.props).forEach( attr => {
                    this.inputField.nativeElement.setAttribute(attr, this.props[attr]);
                });
            }
        }
    }
    

    输入百分比。组成部分html

    <div class="input-group">
        <input type="number" #inputField class="form-control" step="0.01">
        <div class="input-group-append">
            <span class="input-group-text">%</span>
        </div>
    </div>
    

    像这样使用它

    <percent-input [props]="{ style: 'background-color: yellow'  }" ></percent-input>
    

    Demo