所以我想使用 formly-forms 进行垫式自动完成,并在每个自动完成的末尾有一个添加和删除按钮。最重要的是,我希望这个自动完成 + 按钮的“二重奏”占据 100% 的可用宽度。 为了实现这一目标,我为自动完成功能创建了一个自定义类型,并创建了一个包装器来添加按钮(为了示例,我现在仅使用“删除”按钮)。
我面临两大挑战:
这是一个 stackblitz,其中包含问题的重现(直接从 Formly 自动完成示例中分叉出来)。
直接上代码:
App.component.html:
<form [formGroup]="form">
<formly-form [model]="model" [fields]="fields" [options]="options" [form]="form"></formly-form>
</form>
<!-- Copyright 2021 Formly. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at https://github.com/ngx-formly/ngx-formly/blob/main/LICENSE -->
app.component.ts
import { Component } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormlyFormOptions, FormlyFieldConfig } from '@ngx-formly/core';
import { of } from 'rxjs';
const states = [
'Alabama',
'Alaska',
'American Samoa',
'Arizona',
'Arkansas',
'California',
'Colorado',
'Connecticut',
'Delaware',
'District Of Columbia',
'Federated States Of Micronesia',
'Florida',
'Georgia',
'Guam',
'Hawaii',
'Idaho',
'Illinois',
'Indiana',
'Iowa',
'Kansas',
'Kentucky',
'Louisiana',
'Maine',
'Marshall Islands',
'Maryland',
'Massachusetts',
'Michigan',
'Minnesota',
'Mississippi',
'Missouri',
'Montana',
'Nebraska',
'Nevada',
'New Hampshire',
'New Jersey',
'New Mexico',
'New York',
'North Carolina',
'North Dakota',
'Northern Mariana Islands',
'Ohio',
'Oklahoma',
'Oregon',
'Palau',
'Pennsylvania',
'Puerto Rico',
'Rhode Island',
'South Carolina',
'South Dakota',
'Tennessee',
'Texas',
'Utah',
'Vermont',
'Virgin Islands',
'Virginia',
'Washington',
'West Virginia',
'Wisconsin',
'Wyoming',
];
@Component({
selector: 'formly-app-example',
templateUrl: './app.component.html',
})
export class AppComponent {
form = new FormGroup({});
model: any = {};
options: FormlyFormOptions = {};
fields: FormlyFieldConfig[] = [
{
key: 'Autocomplete',
type: 'autocomplete',
wrappers: ['buttonWrapper'],
props: {
required: true,
label: 'Autocomplete',
placeholder: 'Placeholder',
filter: (term: string) =>
of(term ? this.filterStates(term) : states.slice()),
},
},
];
filterStates(name: string) {
return states.filter(
(state) => state.toLowerCase().indexOf(name.toLowerCase()) === 0
);
}
}
/** Copyright 2021 Formly. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at https://github.com/ngx-formly/ngx-formly/blob/main/LICENSE */
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ReactiveFormsModule } from '@angular/forms';
import { FormlyModule } from '@ngx-formly/core';
import { FormlyMaterialModule } from '@ngx-formly/material';
import { MatInputModule } from '@angular/material/input';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { AppComponent } from './app.component';
import { AutocompleteTypeComponent } from './autocomplete-type.component';
import { AutcompleteButtonWrapperComponent } from './custom-wrapper.component';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
@NgModule({
imports: [
BrowserAnimationsModule,
ReactiveFormsModule,
MatInputModule,
MatButtonModule,
MatIconModule,
MatAutocompleteModule,
FormlyMaterialModule,
FormlyModule.forRoot({
types: [
{
name: 'autocomplete',
component: AutocompleteTypeComponent,
wrappers: ['form-field'], // Comment this line and comment out the mat-form-field tag in the autocomplete type to adjust the styling;
},
],
wrappers: [
{
name: 'buttonWrapper',
component: AutcompleteButtonWrapperComponent,
},
],
validationMessages: [
{ name: 'required', message: 'This field is required' },
],
}),
],
bootstrap: [AppComponent],
declarations: [
AutcompleteButtonWrapperComponent,
AutocompleteTypeComponent,
AppComponent,
],
})
export class AppModule {}
/** Copyright 2021 Formly. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at https://github.com/ngx-formly/ngx-formly/blob/main/LICENSE */
自动完成类型.component.ts
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ReactiveFormsModule } from '@angular/forms';
import { FormlyModule } from '@ngx-formly/core';
import { FormlyMaterialModule } from '@ngx-formly/material';
import { MatInputModule } from '@angular/material/input';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { AppComponent } from './app.component';
import { AutocompleteTypeComponent } from './autocomplete-type.component';
import { AutcompleteButtonWrapperComponent } from './custom-wrapper.component';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
@NgModule({
imports: [
BrowserAnimationsModule,
ReactiveFormsModule,
MatInputModule,
MatButtonModule,
MatIconModule,
MatAutocompleteModule,
FormlyMaterialModule,
FormlyModule.forRoot({
types: [
{
name: 'autocomplete',
component: AutocompleteTypeComponent,
wrappers: ['form-field'], // Comment this line and comment out the mat-form-field tag in the autocomplete type to adjust the styling;
},
],
wrappers: [
{
name: 'buttonWrapper',
component: AutcompleteButtonWrapperComponent,
},
],
validationMessages: [
{ name: 'required', message: 'This field is required' },
],
}),
],
bootstrap: [AppComponent],
declarations: [
AutcompleteButtonWrapperComponent,
AutocompleteTypeComponent,
AppComponent,
],
})
export class AppModule {}
/** Copyright 2021 Formly. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at https://github.com/ngx-formly/ngx-formly/blob/main/LICENSE */
自定义包装.component.ts
import { Component } from '@angular/core';
import { FieldWrapper } from '@ngx-formly/core';
@Component({
selector: 'formly-wrapper-button',
template: `
<div style="display: flex; align-items: center; width: 100%;">
<ng-container #fieldComponent></ng-container>
<button mat-icon-button color="warn"><mat-icon>remove</mat-icon></button>
</div>
`,
})
export class AutcompleteButtonWrapperComponent extends FieldWrapper {}
/** Copyright 2021 Formly. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at https://github.com/ngx-formly/ngx-formly/blob/main/LICENSE */
关于如何实现这一目标有什么想法吗?
要宽度100%只需添加styles.css
mat-form-field.full-width { 宽度:100%; } formly-form.全角 formly-autocomplete-type { 宽度:100%; }
然后你在你的组件中使用
<formly-form class="full-width" ....</formly-form>
您的组件应该添加 formField
<mat-form-field class="full-width">
<mat-label>{{ props.label }}</mat-label>
<input
matInput
[matAutocomplete]="auto"
[formControl]="formControl"
[formlyAttributes]="field"
[placeholder]="props.placeholder"
[errorStateMatcher]="errorStateMatcher"
placeholder="Ex. Pizza"
value="Sushi"
/>
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete">
...
</mat-autocomplete>
你的分叉堆栈闪电战
注意:我不知道是否最好不要使用 formly-wrapper-button,否则使用
formly-autocomplete-type
中的所有 logiv,有些像博客的条目 如何使用 Formly 自动生成高级表单