Обратитесь к автозаполнению входов, генерируемых динамически с помощью цикла ngFor. - PullRequest
0 голосов
/ 13 июня 2019

Я устанавливаю угловую страницу счета-фактуры, где строки добавляются динамически, каждая строка должна иметь собственный ввод автозаполнения с другими различными входами. Как я могу ссылаться на каждый ввод автозаполнения независимо внутри моего компонента, чтобы я мог использовать правильный внутри мой дисплей с функцией?

Мой вопрос похож на этот один, но я не могу найти правильный ответ там :(

HTML

<tr *ngFor="let ligneFacture of facture.lignesFacture; let i =index;">
    <td width="5%" align="center">
        <button type="button" class="button btn-primary"
                style="border-radius: 50px;" disabled><span>{{i+1}}</span>
        </button>
    </td>
    <td width="25%">
        <form>
            <mat-form-field>
                <input type="text" class="form-control" matInput
                       (ngModelChange)="watchChangesArticle($event)"
                       (focus)="cursorFocusArticle($event)"
                       [matAutocomplete]="autoArticle"
                       [ngModelOptions]="{standalone: true}"
                       [(ngModel)]="ligneFacture.articleId">
                <mat-autocomplete #autoArticle="matAutocomplete"
                                  [displayWith]="displayFnArticle.bind(this)"
                                  [autoActiveFirstOption]="true">
                    <mat-option *ngFor="let article of articles;"
                                [value]="article.id">
                        {{article.libelle}}
                    </mat-option>
                </mat-autocomplete>
            </mat-form-field>
        </form>
    </td>
    <td width="10%"><input type="text" class="form-control"
                           style="text-align: center"
                           [ngModelOptions]="{standalone: true}"
                           [(ngModel)]="ligneFacture.unite"/>
    <td width="10%"><input type="number" class="form-control" #quantity
                           id="quantity{{i+1}}"
                           [ngModelOptions]="{standalone: true}"
                           [(ngModel)]="ligneFacture.quantite"/>
    </td>
    <td width="13%">
        <div class="input-group">
            <input type="number" class="form-control"
                   [ngModelOptions]="{standalone: true}"
                   [(ngModel)]="ligneFacture.tauxTva" readonly/>
            <div class="input-group-append">
                <span class="input-group-text">%</span>
            </div>
        </div>
    </td>

    <td width="15%"><input type="number" class="form-control"
                           [ngModelOptions]="{standalone: true}"
                           [(ngModel)]="ligneFacture.prixUnitaire" tabindex="-1"
                           [value]="updateChanges(ligneFacture)"
                           readonly/></td>

    <td width="15%"><input type="number" class="form-control"
                           [ngModelOptions]="{standalone: true}"
                           [(ngModel)]="ligneFacture.prixTotal" tabindex="-1" readonly/>
    </td>
    <td>
        <div>
            <button type="button" class="btn btn-danger"
                    (click)="removeLine(ligneFacture)" tabindex="-1">
                <span>[X]</span>
            </button>
        </div>
    </td>
</tr>
<br>
<tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td colspan="2" align="right">
        <button type="button" class="btn btn-primary" (click)="addLine()">
            <span>[+] Ajouter une ligne</span>
        </button>
    </td>
</tr>
1009 * * TS:
export class FactureUpdateComponent implements OnInit {
    @ViewChild('autoArticle') matAutocompleteArticle: MatAutocomplete;
    //
    //

    displayFnArticle(item) {
        const matOptions = this.matAutocompleteArticle.options.filter(x => x.value === item);
        if (matOptions.length !== 0) {
            setTimeout(() => {
                const element = document.getElementById('quantity' + this.facture.lignesFacture.length);
                element.focus();
            }, 0);
            return matOptions.map(x => x.viewValue)[0];
        } else {
            return this.facture.lignesFacture.filter(x => x.articleId === item).map(x => x.articleLibelle);
        }
    }

    watchChangesArticle(event, ligneFacture: ILigneFacture) {
        this.articleService.queryByKeyword(event, this.req).subscribe(
            (res: HttpResponse<IArticle[]>) => {
                ligneFacture.articles = res.body;
            },
            (res: HttpErrorResponse) => this.onError(res.message)
        );
    }

    cursorFocusArticle(event, ligneFacture: ILigneFacture) {
        if (event.target.value === '') {
            this.articleService.queryByKeyword('', this.req).subscribe(
                (res: HttpResponse<IArticle[]>) => {
                    ligneFacture.articles = res.body;
                },
                (res: HttpErrorResponse) => this.onError(res.message)
            );
        }
    }
}

Ожидаемый результат: внутри функции displayFnArticle я могу получить доступ к автозаполнению ввода текущей строки

Фактический результат : я просто получаю доступ к тому же первому идентификатору ввода автозаполнения, который может вызывать следующую дисфункцию

Ответы [ 2 ]

1 голос
/ 13 июня 2019

Вы можете использовать шаблоны ссылок там.Документы: https://angular.io/guide/template-syntax#template-reference-variables--var-.

Пример здесь: https://stackblitz.com/edit/angular-template-ref-with-fn

Итак, у вас есть такой HTML-код:

<button *ngFor="let i of array" #ref (click)="doStuff(ref)" class="{{ 'a' + i }}">{{ 'a' + i }}</button>

И вы справляетесь с этим следующим образом:

doStuff(instance: HTMLElement) {
  console.log('>> stuff', instance.classList);
}

Это просто пример с простыми элементами, но вы можете сделать то же самое с MatAutocomplete.

0 голосов
/ 13 июня 2019

Я получил решение с некоторой помощью, найденное здесь в комментариях к шаблонной ссылочной переменной:

Теперь у меня есть доступ к текущему автозаполнению непосредственно в моем компоненте, и мне больше не нужен @ ViewChild

HTML:

  <mat-autocomplete #autoArticle="matAutocomplete" #currentAutocomplete
        [displayWith]="displayFnArticle.bind(this, currentAutocomplete)" [autoActiveFirstOption]="true">
          <mat-option *ngFor="let article of articles;"
                                [value]="article.id">
                        {{article.libelle}}
          </mat-option>
  </mat-autocomplete>

TS:

    displayFnArticle(autocomplete: MatAutocomplete, item) {
        const matOptions = autocomplete.options.filter(x => x.value === item);
        if (matOptions.length !== 0) {
            setTimeout(() => {
                const element = document.getElementById('quantity' + this.facture.lignesFacture.length);
                element.focus();
            }, 0);
            return matOptions.map(x => x.viewValue)[0];
        } else {
            return this.facture.lignesFacture.filter(x => x.articleId === item).map(x => x.articleLibelle);
        }
    }
...