Поле, предварительно заполненное значением, не активирует анимацию метки в среде начальной загрузки MD

Я использую урезанную версию MDBootstrap(A) для дизайна материалов на полях. В одном поле после нажатия кнопки сброса значение предварительно заполнено. Но анимация метки не активируется, когда это происходит, поэтому значение и метка перекрываются.

Кстати, это происходит при первой загрузке страницы. Это на самом деле работает, когда загружается со значением в, но не работает, когда я удаляю значение становится недействительным, тогда я сбрасываю поля кнопкой. Значение возвращается, но активация метки для анимации не происходит. Может быть, это проблема CSS.

<div class="md-form form-group">
               <input  type="text"
                       id="portalName"
                       mdbActive
                       [ngClass]="{'invalid':(portal.errors && portal.touched) || (portal.errors && portal.dirty), 'valid':(!portal.errors && portal.touched) || (!portal.errors && portal.dirty)}"
                       class="form-control"
                       name="portalName"
                       [(ngModel)]="portalName.companyName"
                       #portal="ngModel"
                       [maxlength]="12"
                       required />
                <label for="portalName">{{"CUSTOM_BRANDING.LABELS.BESPOKE_NAME" | translate }}</label>

                <div *ngIf="portal.errors && (portal.dirty || portal.touched)"
                     class="message position-absolute">
                    <div [hidden]="!portal.errors.required" class="error-message" >
                        {{"CUSTOM_BRANDING.ERRORS.REQUIRED" | translate }}
                    </div>
                    <div [hidden]="!portal.errors.maxlength" class="error-message" >
                        {{"CUSTOM_BRANDING.ERRORS.MAX_LENGTH" | translate }}
                    </div>
                </div>
            </div>

Я должен сказать, что я довольно новичок в работе с angular 2. Я пытаюсь создать что-то внутри компонента, чтобы при сбросе и заполнении значения, по крайней мере, сделать проверку поля, например setTouched или reset. Не уверен, что лучше. У меня есть этот код в компоненте, контролирующем шаблон

 resetCustBrand = (): void => {
    this.facade.resetBrandLogoAndName(this.facade.CommonNodeModel.SelectedNode.Id)
        .subscribe({
            complete: () => {
                this.selectedNodeChanged(this.facade.CommonNodeModel.SelectedNode);
                this.translator.getTranslationBaseOnKey("CUSTOM_BRANDING.TOASTER_RESET_BRANDING").subscribe((message: string) => {
                    const toasterMessage = message.split(',');
                    this.toaster.pop("success", toasterMessage[0], toasterMessage[1]);
                });
            },
            error: () => this.translator.getTranslationBaseOnKey("CUSTOM_BRANDING.ERRORS.RESETING_BRANDING").subscribe((errorMessage: string) => this.notifyService.notifyUser(errorMessage))
        });
}

Я надеюсь, что я могу добавить что-то здесь, чтобы установить поле снова.

0 ответов

Метка должна быть активной, когда поле предварительно заполнено / заполнено.

Вы можете попробовать приведенный ниже код:

<label class="active" *ngIf="portalName != null; else not">  <!-- portalName should be replace with your data on input -->
  {{"CUSTOM_BRANDING.LABELS.BESPOKE_NAME" | translate }}  <!-- Your label Name -->
</label>

<ng-template #not>
  <label class="">
    {{"CUSTOM_BRANDING.LABELS.BESPOKE_NAME" | translate }}  <!-- Your label Name -->
  </label>
</ng-template>

Этот подход решил мою проблему.

MD bootstrap 5.2.3 исправляет эту проблему, используя ловушку жизненного цикла AfterViewCheck и выполняет другую инициализацию для ввода onAfterViewCheck.

Это дополнительно обрабатывается в новых обновлениях с DoCheck. Мы не можем обновить дальше, чем 5.3.2, потому что тогда вам нужно angular 6 в вашем приложении.

Но мы создали обходной путь с этим кодом.

import {AfterViewInit, Directive, DoCheck, ElementRef, HostListener, 
Input, Renderer2} from '@angular/core';

@Directive({
selector: '[mdbActive]'
})    
export class ActiveDirective implements AfterViewInit, DoCheck {

public el: ElementRef;
public elLabel: ElementRef;
public elIcon: Element;

constructor(el: ElementRef, public renderer: Renderer2) {
    this.el = el;
}

@HostListener('focus', ['$event']) onClick() {
    this.initComponent();
}

@HostListener('blur', ['$event']) onBlur() {
    this.checkValue();
}

@HostListener('change', ['$event']) onChange() {
    this.checkValue();
}

ngDoCheck() {
    this.checkValue();
}

ngAfterViewInit() {
    this.initComponent();
    this.checkValue();
    setTimeout(() => {
        this.checkValue();
    }, 0);
}

private initComponent(): void {
    let inputId;
    let inputP;

    try {
        inputId = this.el.nativeElement.id;
    } catch (err) {}

    try {
        inputP = this.el.nativeElement.parentNode;
    } catch (err) {}


    this.elLabel = inputP.querySelector('label[for="' + inputId + '"]') || inputP.querySelector('label');
    if (this.elLabel != null) {
        this.renderer.addClass(this.elLabel, 'active');
    }

    this.elIcon = inputP.querySelector('i') || false;

    if (this.elIcon) {
        this.renderer.addClass(this.elIcon, 'active');
    }
}

// May need to change to public so can be called from component.
// This may be required so that changes applied after losing focus (e.g. typeahead) can be checked for
// if the ngDoCheck event doesn't fire.
private checkValue(): void {
    let value = '';
    if (this.elLabel != null) {
        value = this.el.nativeElement.value || '';
        if (value === '') {
            this.renderer.removeClass(this.elLabel, 'active');
            if (this.elIcon) {
                this.renderer.removeClass(this.elIcon, 'active');
            }
        } else {
            this.renderer.addClass(this.elLabel, 'active');
        }
    }
}

}

Другие вопросы по тегам