Angular 4 ngIf внутри ngFor не работает должным образом

Проблема, с которой я сталкиваюсь, заключается в том, что я не получаю ожидаемую функциональность из моего оператора * ngIf внутри * ngFor. Я использую его для перебора пользовательских сообщений проверки, и каждый ngIf имеет уникальный оператор. Ниже приведен файл component.html, с которым я работаю:

<div class="form-group">
<label for="{{title}}">First Name:</label>
<input type="text" class="form-control" id="{{title}}" name="{{title}}" [(ngModel)]="vm.title" [ngModelOptions]="{standalone: true}" #title="ngModel" minlength="{{minLength}}" maxlength="{{maxLength}}" required />
<div *ngIf="title.errors && (title.dirty || title.touched)" class="alert alert-danger">
    <div *ngFor="let validation of validations">
        <div *ngIf="validation.method">{{validation.message}}</div>
    </div>
</div>

And here is the component.ts file:

import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';

@Component({
    selector: 'textbox',
    templateUrl: './textbox.component.html',
    styleUrls: ['./textbox.component.css']
})

export class TextboxComponent implements OnInit {
    @Input('title') title: string;
    @Input('required') required: boolean;
    @Input('required-message') requiredMessage: string;
    @Input('min-length') minLength: number;
    @Input('min-length-message') minLengthMessage: string;
    @Input('max-length') maxLength: number;
    @Input('max-length-message') maxLengthMessage: string;
    validations: Validation[] = [];

    public vm: SignUp;

    ngOnInit() {
        this.vm = new SignUp();
        if (this.required) {
            if (this.requiredMessage[0] != "") {
                this.validations.push(new Validation(this.title + ".errors.required", this.requiredMessage));
            } else {
                this.validations.push(new Validation("!" + this.title + ".errors.required", "First name is required"));
            }
        } else {
            //make not required
        }
        if (this.minLength) {
            if (this.minLengthMessage) {
                this.validations.push(new Validation(this.title + ".errors.minlength", this.minLengthMessage));
            } else {
                this.validations.push(new Validation("!" + this.title + ".errors.minlength", "Minimun length is " + this.minLength));
            }
        }
        if (this.maxLength) {
            if (this.maxLengthMessage) {
                this.validations.push(new Validation(this.title + ".errors.maxlength", this.maxLengthMessage));
            } else {
                this.validations.push(new Validation("!" + this.title + ".errors.maxlength", "Maximun length is " + this.maxLength));
            }
        }
        for (var i = 0; i > this.validations.length; i++) {
            console.log(this.validations[i].method);
            console.log(this.validations[i].message);
        }
    }
}
export class SignUp {
    nameFirst: string;
    nameLast: string;
    username: string;
    password: string;
}
export class Validation {
    constructor(public method: string, public message: string) {
        console.log(method);
        console.log(message);
    }
}

Я вызываю компонент из другого компонента следующим образом:

<div class="row">
    <form #form="ngForm">
        <div class="form-group">
            <textbox [title]="'nameFirst'" [required]="true" [required-message]="'required message test'" [min-length]="5" [min-length-message]="'minimum length test'" [max-length]="10" [max-length-message]="'maximum length test'"></textbox>
        </div>
    </form>
</div>

В конечном итоге происходит то, что все сообщения проверки отображаются независимо от того, должны ли они запускаться. Например, отображается «тест на максимальную длину», хотя я и не приближаюсь к максимальному количеству символов.

Вот plunkr, чтобы поиграть с функциональностью: https://plnkr.co/edit/IgQ9WxSHVaTz7zz0aajU


person app1001    schedule 14.08.2017    source источник


Ответы (2)


<div *ngIf="validation.method">{{validation.message}}</div>

У вас отображается сообщение, пока существует validation.method. Каждый раз, когда вы создаете Validation, вы делаете это так:

new Validation(this.title + ".errors.minlength", this.minLengthMessage)

Свойство Validation method имеет значение string и никогда не бывает пустым, поэтому директива *ngIf всегда оценивается как true.

person Jun Kang    schedule 14.08.2017

Что сказал Джун Кан. Кроме того, кажется, что вы делаете очень много работы, которая вам не нужна. Вы изучали создание реактивных форм? Вот краткий пример:

  createForm() {
    this.heroForm = this.fb.group({
      name: ['', Validators.required ],
      street: ['', [Validators.minLength(6), Validators.required]]
    });
  }

Тогда вы просто используете ngIf для каждого валидатора в вашем HTML. Пройдитесь по примеру Angular. Это полезно, и с вашим кодом будет проще работать: https://angular.io/guide/reactive-forms

person Notmfb    schedule 14.08.2017
comment
Я тоже собирался упомянуть об этом, но подумал, что в исходном вопросе нет необходимости. Но да, он делает работу, которая ему не нужна. Он мог даже просто использовать шаблонную форму. Поскольку Validation, которые он использует, это всего лишь required, min-length и max-length, которые являются валидаторами, уже встроенными в формы, управляемые шаблонами Angular. - person Jun Kang; 14.08.2017
comment
Абсолютно верно. Просто казалось, что он делал всю эту дополнительную работу, в которой не нуждался. Для этого варианта использования подойдет либо подход, основанный на шаблонах, либо подход с реактивными формами. - person Notmfb; 14.08.2017
comment
Я немного изучил реактивные формы, и, насколько я могу судить, использование одной из них противоречит цели того, что я пытаюсь здесь сделать. То, что я собираюсь сделать, это отдельные входные данные формы, которые являются модульными и могут быть вызваны из любого места и настроены там, где они вызываются. Чего я не хочу, так это всей формы, так как мне могут понадобиться входные данные, селекторы и радиусы в одном месте и всего пара входных данных в другом. Мне также могут понадобиться входные данные, которые могут потребоваться или не потребоваться (определяются вызывающим абонентом). - person app1001; 14.08.2017