Поле, предварительно заполненное значением, не активирует анимацию метки в среде начальной загрузки 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');
}
}
}
}