造型正式表单自定义包装+自定义类型

问题描述 投票:0回答:1

所以我想使用 formly-forms 进行垫式自动完成,并在每个自动完成的末尾有一个添加和删除按钮。最重要的是,我希望这个自动完成 + 按钮的“二重奏”占据 100% 的可用宽度。 为了实现这一目标,我为自动完成功能创建了一个自定义类型,并创建了一个包装器来添加按钮(为了示例,我现在仅使用“删除”按钮)。

我面临两大挑战:

  1. 其一,当使用自定义类型的包装器时,mat-form-field 样式会变得混乱。我有一个修复方法,即删除“表单字段”包装器声明以及 formly 配置中的自定义类型声明,并直接在自动完成自定义类型中使用标签手动添加此“表单字段”。
  2. 如果我执行前面的操作,宽度总是会变得混乱,并且“二重奏”要么由于某种原因仅占用可用宽度的 33% 左右,要么(如果我在 中应用 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 */

关于如何实现这一目标有什么想法吗?

angular angular-formly ngx-formly
1个回答
0
投票

要宽度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 自动生成高级表单

© www.soinside.com 2019 - 2024. All rights reserved.