<legend id='S2uNF'><style id='S2uNF'><dir id='S2uNF'><q id='S2uNF'></q></dir></style></legend>
      <tfoot id='S2uNF'></tfoot>

      <small id='S2uNF'></small><noframes id='S2uNF'>

        • <bdo id='S2uNF'></bdo><ul id='S2uNF'></ul>
        <i id='S2uNF'><tr id='S2uNF'><dt id='S2uNF'><q id='S2uNF'><span id='S2uNF'><b id='S2uNF'><form id='S2uNF'><ins id='S2uNF'></ins><ul id='S2uNF'></ul><sub id='S2uNF'></sub></form><legend id='S2uNF'></legend><bdo id='S2uNF'><pre id='S2uNF'><center id='S2uNF'></center></pre></bdo></b><th id='S2uNF'></th></span></q></dt></tr></i><div id='S2uNF'><tfoot id='S2uNF'></tfoot><dl id='S2uNF'><fieldset id='S2uNF'></fieldset></dl></div>

      1. Angular ngx-mat-select-search 自定义组件

        时间:2023-09-30
          • <bdo id='YpZwz'></bdo><ul id='YpZwz'></ul>

            <small id='YpZwz'></small><noframes id='YpZwz'>

          • <tfoot id='YpZwz'></tfoot>

              1. <i id='YpZwz'><tr id='YpZwz'><dt id='YpZwz'><q id='YpZwz'><span id='YpZwz'><b id='YpZwz'><form id='YpZwz'><ins id='YpZwz'></ins><ul id='YpZwz'></ul><sub id='YpZwz'></sub></form><legend id='YpZwz'></legend><bdo id='YpZwz'><pre id='YpZwz'><center id='YpZwz'></center></pre></bdo></b><th id='YpZwz'></th></span></q></dt></tr></i><div id='YpZwz'><tfoot id='YpZwz'></tfoot><dl id='YpZwz'><fieldset id='YpZwz'></fieldset></dl></div>

                    <tbody id='YpZwz'></tbody>
                1. <legend id='YpZwz'><style id='YpZwz'><dir id='YpZwz'><q id='YpZwz'></q></dir></style></legend>

                2. 本文介绍了Angular ngx-mat-select-search 自定义组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在尝试使用 ngx-mat-select-search 组件在我的应用程序中放置一个带有搜索栏的 mat-select 样式下拉菜单.https://www.npmjs.com/package/ngx-mat-select-search

                  I am trying to use the ngx-mat-select-search component to put a mat-select style dropdown menu with a search bar in my application. https://www.npmjs.com/package/ngx-mat-select-search

                  我的下拉菜单工作正常,但我正在尝试将其转换为自定义指令,然后我可以在整个应用程序的多个页面上调用和重用该指令.

                  I have the dropdown working fine, but I am trying to turn it into a custom directive that I can then call and reuse on multiple pages through out the app.

                  到目前为止,我有这个:site-dropdown-component.ts

                  So far I have this: site-dropdown-component.ts

                  import {AfterViewInit, Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
                  import {FormControl} from '@angular/forms';
                  import {ReplaySubject, Subject} from 'rxjs';
                  import {MatSelect} from '@angular/material';
                  import {take, takeUntil} from 'rxjs/operators';
                  
                  @Component({
                    selector: 'app-site-dropdown',
                    template: `
                      <mat-form-field class="w-100">
                        <mat-select [formControl]="siteCtrl" placeholder="Site" #singleSelect>
                          <mat-option>
                            <ngx-mat-select-search [formControl]="siteFilterCtrl" [placeholderLabel]="'Search Sites...'"></ngx-mat-select-search>
                          </mat-option>
                          <mat-option *ngFor="let site of filteredSites | async" [value]="site">{{site.name}}</mat-option>
                        </mat-select>
                      </mat-form-field>
                    `
                  })
                  export class SiteDropdownComponent implements OnInit, OnDestroy, AfterViewInit {
                    /** list of sites */
                    protected sites: Site[] = SITES;
                  
                    /** control for the selected site */
                    public siteCtrl: FormControl = new FormControl();
                  
                    /** control for the MatSelect filter keyword */
                    public siteFilterCtrl: FormControl = new FormControl();
                  
                    /** list of sites filtered by search keyword */
                    public filteredSites: ReplaySubject<Site[]> = new ReplaySubject<Site[]>(1);
                  
                    @ViewChild('singleSelect') singleSelect: MatSelect;
                  
                    /** Subject that emits when the component has been destroyed. */
                    protected onDestroy = new Subject<void>();
                    constructor() { }
                  
                    ngOnInit(): void {
                      // set initial selection
                      this.siteCtrl.setValue(this.sites);
                      // load the initial site list
                      this.filteredSites.next(this.sites.slice());
                      // listen for search field value changes
                      this.siteFilterCtrl.valueChanges
                        .pipe(takeUntil(this.onDestroy))
                        .subscribe(() => {
                          this.filterSites();
                        });
                    }
                  
                    ngAfterViewInit(): void {
                      this.setInitialValue();
                    }
                  
                    ngOnDestroy(): void {
                      this.onDestroy.next();
                      this.onDestroy.complete();
                    }
                  
                    /**
                     * Sets the initial value after the filteredBanks are loaded initially
                     */
                    protected setInitialValue() {
                      this.filteredSites
                        .pipe(take(1), takeUntil(this.onDestroy))
                        .subscribe(() => {
                          // setting the compareWith property to a comparison function
                          // triggers initializing the selection according to the initial value of
                          // the form control (i.e. _initializeSelection())
                          // this needs to be done after the filteredBanks are loaded initially
                          // and after the mat-option elements are available
                          this.singleSelect.compareWith = (a: Site, b: Site) => a && b && a.id === b.id;
                        });
                    }
                  
                    protected filterSites() {
                      if (!this.sites) {
                        return;
                      }
                      // get the search keyword
                      let search = this.siteFilterCtrl.value;
                      if (!search) {
                        this.filteredSites.next(this.sites.slice());
                        return;
                      } else {
                        search = search.toLowerCase();
                      }
                      // filter the sites
                      this.filteredSites.next(
                        this.sites.filter(site => site.name.toLowerCase().indexOf(search) > -1)
                      );
                    }
                  }
                  
                  
                  export interface Site {
                    id: string;
                    name: string;
                  }
                  
                  export const SITES: Site[] = [
                    {id: 'site1', name: 'Site 1'},
                    {id: 'site2', name: 'Site 2'},
                    {id: 'site3', name: 'Site 3'},
                  ];
                  

                  对于我尝试使用它的组件,我有:

                  For the component im trying to use it in, i have:

                  <app-site-dropdown formControlName="site"></app-site-dropdown>
                  

                  在组件类里面我有一个表单:

                  And inside the component class I have a form:

                  this.mySearchForm = this.formBuilder.group( {
                    site: []
                  }); 
                  

                  我可以很好地查看下拉列表并与之交互,但是当我提交表单时,我无法获得所选选项的值.当我尝试 mySearchForm.controls['site'].value

                  I can see and interact with the dropdown just fine, but when i submit my form, I cannot get the value of the selected option. It just always returns null when i try mySearchForm.controls['site'].value

                  我缺少什么能够注入我的自定义下拉组件并在提交表单时检索其值?

                  What am I missing to be able to inject my custom dropdown component, and retrieve its value upon form submission?

                  更新:

                  我能够通过执行以下操作使其工作:

                  I was able to make it work by doing the following:

                  site-dropdown.component.ts里面,我改了

                  protected siteCtrl: FormControl;
                  

                  @Input() siteCtrl: FormControl;
                  

                  在我的 html 中使用自定义下拉菜单,我添加了:

                  And inside my html using the custom dropdown, i added:

                  <app-site-dropdown [siteCtrl]="myForm.get('site')"></app-site-dropdown>
                  

                  这使我可以在提交时将所选值保存到我的表单中.

                  This allowed me to save the selected value into my form on submission.

                  推荐答案

                  您可以通过让您的 SiteDropdownComponent 实现 ControlValueAccessor 接口如下,导致您的 SiteDropdownComponent 表现为表单控件并允许使用例如访问值<app-site-dropdown formControlName="site"></app-site-dropdown>:

                  you can get the value of the selected option by having your SiteDropdownComponent implement the ControlValueAccessor interface as follows, resulting in your SiteDropdownComponent behaving as a form control and allowing to access the value with e.g. <app-site-dropdown formControlName="site"></app-site-dropdown>:

                  ...
                  import { forwardRef } from '@angular/core';
                  import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
                  
                  @Component({
                    selector: 'app-site-dropdown',
                    template: ...
                    providers: [
                      {
                        provide: NG_VALUE_ACCESSOR,
                        useExisting: forwardRef(() => SiteDropdownComponent),
                        multi: true
                      }
                    ],
                  })
                  export class SiteDropdownComponent implements OnInit, OnDestroy, AfterViewInit, ControlValueAccessor {
                    ...
                  
                    onChange: Function = (_: any) => {};
                    onTouched: Function = (_: any) => {};
                  
                    constructor() { }
                  
                    ngOnInit() {
                      ...
                      // call this.onChange to notify the parent component that the value has changed
                      this.siteCtrl.valueChanges
                        .pipe(takeUntil(this.onDestroy))
                        .subscribe(value => this.onChange(value))
                    }
                  
                    writeValue(value: string) {
                      // set the value of siteCtrl when the value is set from outside the component
                      this.siteCtrl.setValue(value);
                    }
                  
                    registerOnChange(fn: Function) {
                      this.onChange = fn;
                    }
                  
                    registerOnTouched(fn: Function) {
                      this.onTouched = fn;
                    }
                  
                  }
                  

                  参见例如https://github.com/bithost-gmbh/ngx-mat-select-search/blob/d7ea78d511bbec45143c58c855f013a44d0d5055/src/app/mat-select-search/mat-select-search.component.ts#L134

                  这篇关于Angular ngx-mat-select-search 自定义组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:以角度将数据从一个组件传递到另一个组件 下一篇:Angular Component:没有模板替换选项?

                  相关文章

                  1. <i id='Qqqeo'><tr id='Qqqeo'><dt id='Qqqeo'><q id='Qqqeo'><span id='Qqqeo'><b id='Qqqeo'><form id='Qqqeo'><ins id='Qqqeo'></ins><ul id='Qqqeo'></ul><sub id='Qqqeo'></sub></form><legend id='Qqqeo'></legend><bdo id='Qqqeo'><pre id='Qqqeo'><center id='Qqqeo'></center></pre></bdo></b><th id='Qqqeo'></th></span></q></dt></tr></i><div id='Qqqeo'><tfoot id='Qqqeo'></tfoot><dl id='Qqqeo'><fieldset id='Qqqeo'></fieldset></dl></div>
                      <bdo id='Qqqeo'></bdo><ul id='Qqqeo'></ul>

                  2. <small id='Qqqeo'></small><noframes id='Qqqeo'>

                    <legend id='Qqqeo'><style id='Qqqeo'><dir id='Qqqeo'><q id='Qqqeo'></q></dir></style></legend>

                    <tfoot id='Qqqeo'></tfoot>