首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在使用css下拉列表作为共享组件时设置和获取窗体值

如何在使用css下拉列表作为共享组件时设置和获取窗体值
EN

Stack Overflow用户
提问于 2019-04-24 08:44:55
回答 3查看 318关注 0票数 1

我有一个共享组件,它是一个html和css下拉列表。我从具有不同数据的父组件调用这个共享组件。

例如,我有3个来自父组件的共享组件实例,因此父窗体组将有3个formControls。因为所有3种窗体控件现在都是共享组件。如何从所有三个下拉列表中设置和获取选定的数据。

另外,如果为任何下拉列表设置任何默认项,我们如何实现它。

这里的主要目标是访问/获取父组件表单组中的所有formControlName值。

我已经附上了演示代码https://stackblitz.com/edit/angular-mncdy5,请帮助,因为我是在学习阶段!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-04-24 08:50:15

您需要在共享组件中实现ControlValueAccessors,以便在父组件中将formControls附加到它们。这里有一篇很棒的文章,直接介绍了它的价值。

https://medium.com/@majdasab/implementing-control-value-accessor-in-angular-1b89f2f84ebf

这就是customDropdown组件实现ControlValueAccessors所需的外观。

代码语言:javascript
运行
复制
import { OnInit } from '@angular/core';
import { Component, forwardRef, HostBinding, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-common-dropdown',
  templateUrl: './common-dropdown.component.html',
  styleUrls: ['./common-dropdown.component.css'],
  providers: [     
      {       provide: NG_VALUE_ACCESSOR, 
              useExisting: forwardRef(() => CommonDropdownComponent),
              multi: true     
      }
    ] 
})
export class CommonDropdownComponent implements ControlValueAccessor {

  @Input() placeHolder: string;
  @Input() dropDownId: string;
  @Input() dataList: any;

  onChange: any = () => {}
  onTouch: any = () => {}
  val= "" // this is the updated value that the class accesses

  set value(val){  // this value is updated by programmatic changes if( val !== undefined && this.val !== val){
    this.val = val
    this.onChange(val)
    this.onTouch(val)
  }


  constructor() { }

  ngOnInit() {
  }

  // this method sets the value programmatically
  writeValue(value: any){ 
    this.value = value
  }
  registerOnChange(fn: any){
    this.onChange = fn
  }
  registerOnTouched(fn){
    this.onTouch = fn
  }

  propagateChange(_){

  }

  selectClicked(event: any) {
    const ele = event.srcElement.parentNode;
    ele.classList.toggle('cs-active');
  }

  selectedOption(ctrl: string, value: string) {
    this.onChange(value) // <-- CRUCIAL need to inform formControl to update the value 
    document.getElementById(ctrl).innerHTML = value;
    const ele = document.getElementById(ctrl).parentElement;
    ele.classList.toggle('cs-active');
  }

  closeDropDown(event: any) {
    const ele = event.srcElement;
    ele.classList.remove('cs-active');
  }
}

现在我们已经添加了将formControls附加到自定义组件的功能,您可以将它们添加到app.component中的html中:

代码语言:javascript
运行
复制
<form [formGroup]="parentForm">
    <app-common-dropdown placeHolder="select district" [dropDownId]="'districtLabel'" [dataList]="['bangalore','chennai','pune']" formControlName="district" ></app-common-dropdown>
    <app-common-dropdown placeHolder="select distance" [dropDownId]="'distanceLabel'" [dataList]="[100,200,300,400]" formControlName="distance" ></app-common-dropdown>
    <app-common-dropdown placeHolder="select state" [dropDownId]="'stateLabel'" [dataList]="['karnataka','tamil nadu','mumbai']" formControlName="state"  ></app-common-dropdown>
</form>

<button type="submit" (click)="getFormValues()">submit</button>

您需要调整formGroup中的名称,因为它们与html表单不匹配。

代码语言:javascript
运行
复制
this.parentForm = this.fb.group({
  district: ['bangalore', Validators.required], <--- SETS THE DEFAULT VALUE OF THE FORM CONTROL
  distance: [''],
  state:['']
});

formControlName需要匹配parentForm中的一个属性。

票数 3
EN

Stack Overflow用户

发布于 2019-04-24 08:54:43

我已经更改了yout演示代码,请查看这里:https://stackblitz.com/edit/angular-sge8r3

CommonDropdownComponent中,我添加了一个Output(),它发出从下拉列表中选择的值:

代码语言:javascript
运行
复制
@Output() selectedValue: EventEmitter<string> = new EventEmitter<string>();

我还更改了selectedOpiton方法,使其能够发出选定的值:

代码语言:javascript
运行
复制
selectedOption(ctrl: string, value: string) {
  document.getElementById(ctrl).innerHTML = value;
  const ele = document.getElementById(ctrl).parentElement;
  ele.classList.toggle('cs-active');
  this.selectedValue.emit(value);
}

然后在AppComponent中,我将从子组件中得到值,并在AppComponent中设置一个变量

例如,对于第一个下拉列表:

代码语言:javascript
运行
复制
<app-common-dropdown placeHolder="select district" [dropDownId]="'districtLabel'" [dataList]="['bangalore','chennai','pune']" (selectedValue)="setDistrict($event)"></app-common-dropdown>

然后在ts文件中创建了一个方法setDistrict()

代码语言:javascript
运行
复制
setDistrict(value: string): void {
  this.district = value;
}

您还可以在这里阅读更多关于父子交互的内容:https://angular.io/guide/component-interaction

票数 2
EN

Stack Overflow用户

发布于 2019-04-24 09:07:30

要做到这一点,有多种方法。@porgo是一种方法。有关使用@ViewChild的实现,请查看下面的url。

https://stackblitz.com/edit/angular-k92uxr

请参阅下面的url以获取通信b.w组件

https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55825893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档