【问题标题】:Submit a form made of multiple components提交由多个组件组成的表单
【发布时间】:2016-04-27 19:57:13
【问题描述】:

我最近开始使用 Angular2,但遇到了问题。我想创建一个表单来生成一些多项选择题,这是我的问题:

我有一个显示表单布局的 FormComponent。 可以将 AnswerComponent 添加到 FormComponent 以提供有关问题的多种选择。 我一直在使用 DynamicComponentLoader 以编程方式将这些 AnswerComponent 添加到我的 FormComponent 中。

问题是提交按钮必须属于 FormComponent,我不知道如何提醒我的 AnswerComponent 将他们的数据发送到 FormComponent,以便它可以收集所有数据并创建我的问题。

如果有人有一个很棒的想法!

谢谢!

【问题讨论】:

    标签: javascript forms events components angular


    【解决方案1】:

    我们来取样。我有一个管理公司详细信息的表单:

    <form [ngFormModel]="companyForm">
      <field label="Name" [state]="companyForm.controls.name">
        <input [ngFormControl]="companyForm.controls.name" [(ngModel)]="company.name"/> {{name.valid}}
      </field>
      <field label="Tags">
        <tags [(labels)]="company.labels"></tags>
      </field>
    
      <button type="submit" [disabled]="!companyForm.valid">Submit</button>
    </form>
    

    如你所见,我使用了两个子组件:

    • field 旨在使用 Bootstrap3 为字段块构建布局。它接受一个可变区域来提供表单元素(输入、选择、文本区域)。该组件还利用关联的控件来显示验证错误(如果有)。
    • tags 管理作为字符串列表的tags 属性。它允许显示、添加和删除标签。

    您可以看到每个表单元素都利用了两种方式绑定。这意味着每个表单元素都与组件对象的属性相关联。这里company 是组件的一个属性。

    这意味着当你想提交表单时,你可以使用这个company对象来构建例如对应的HTTP请求的payload。

    让我们更多地处理与company 对象相关联的内容。对于输入,很明显使用具有以下语法的 ngModel 指令:[(ngModel)]。使用tags 子组件,它可能不那么明显。

    事实上,您需要定义输入和输出以通过两种方式绑定来管理labels

    @Input labels:string[]
    @Output labelsChanged: EventEmitter
    

    标签更新时,需要调用labelsChangedemit方法。

    这是TagsComponent 组件的完整代码:

    @Component({
      selector: 'tags',
      template: `
        <div *ngIf="labels">
          <span *ngFor="#label of labels" style="font-size:14px"
              class="label label-default" (click)="removeLabel(label)">
            {{label}} <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
          </span>
          <span>&nbsp;|&nbsp;</span>
          <span style="display:inline-block;">
            <input [(ngModel)]="labelToAdd" style="width: 50px; font-size: 14px;" class="custom"/>
            <em class="glyphicon glyphicon-ok" aria-hidden="true" (click)="addLabel(labelToAdd)"></em>
          </span>
        </div>
      `
    })
    export class TagsComponent implements OnInit {
      @Input()
      labels:string[];
      @Output()
      labelsChange: EventEmitter;
    
      constructor(private elementRef:ElementRef) {
        this.labelsChange = new EventEmitter();
      }
    
      removeLabel(label:string) {
        var index = this.labels.indexOf(label, 0);
        if (index != undefined) {
           this.labels.splice(index, 1);
           this.labelsChange.emit(this.labels);
        }
      }
    
      addLabel(label:string) {
        this.labels.push(this.labelToAdd);
        this.labelsChange.emit(this.labels);
        this.labelToAdd = '';
      }
    }
    

    希望对你有帮助 蒂埃里

    【讨论】:

    • 在您的标签组件中,Angular 如何知道输入标签和输出标签更改是双向绑定,而不仅仅是像这样的输入和输出:?
    • 事实上,通过转换,如果您有一个名为something 的输入和一个名为somethingChanged 的输出,您可以使用语法[(something)] 来利用此元素的两种方式绑定;-)
    猜你喜欢
    • 2020-01-07
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    • 2016-06-11
    • 1970-01-01
    • 2012-11-07
    相关资源
    最近更新 更多