Closed JaneSjs closed 1 year ago
I got a reply from our developer (thank you @dk981234 !).
SurveyJS Angular Components (a survey runner and survey creator) work in zoneless mode. This means that they use their own change detection mechanism and track changes to update UI components when it's required. This is the reason why a custom input was not updated as you expected: simply because a creator doesn't detect changes of your custom input.
To handle this correctly, we suggest either of the following options.
this.changeDetectorRef.detectChanges()
within the focus and onblur eventsSubscribe to the focus
and onblur
events of your input
and invoke a custom update
function. Within the update function, call the this.changeDetectorRef.detectChanges()
function to trigger change detection.
The updated demo is available at creator-with-material-custom-tab_option1.zip.
custom-tab.component.html
<mat-form-field>
<mat-label>Input label</mat-label>
<input matInput (focus)="update()" (blur)="update()">
</mat-form-field>
custom-tab.component.ts
import { ChangeDetectorRef, Component } from '@angular/core';
@Component({
selector: 'app-custom-tab',
templateUrl: './custom-tab.component.html',
styleUrls: ['./custom-tab.component.scss']
})
export class CustomTabComponent {
constructor(private changeDetectorRef: ChangeDetectorRef) {
}
public update() {
this.changeDetectorRef.detectChanges();
}
}
To integrate your custom form field seamlessly into the Angular application's change detection and rendering cycle, you'll create a wrapper component (named 'custom-tab.component.ts'). This wrapper will encapsulate your custom form field component and ensure that the Angular zone mechanism (NgZone) is applied for efficient change detection within the custom component.
A custom component wrapper (custom-tab.component.ts):
import { DomPortalOutlet, ComponentPortal } from '@angular/cdk/portal';
import { ApplicationRef, Component, createComponent, ComponentRef, ElementRef, Injector, OnDestroy, OnInit, ViewChild, ViewContainerRef, EnvironmentInjector } from '@angular/core';
import { CustomTabContentComponent } from './custom-tab-content.component';
@Component({
selector: 'app-custom-tab',
templateUrl: './custom-tab.component.html',
styleUrls: ['./custom-tab.component.scss']
})
export class CustomTabComponent implements OnInit, OnDestroy {
@ViewChild("container", { static: true }) containerRef!: ElementRef<HTMLDivElement>;
private component!: ComponentRef<CustomTabContentComponent>;
constructor(private appRef: ApplicationRef, private injector: EnvironmentInjector){
}
ngOnInit() {
this.component = createComponent(CustomTabContentComponent, { environmentInjector: this.injector });
this.containerRef.nativeElement.appendChild(this.component.location.nativeElement);
this.appRef.attachView(this.component.hostView);
}
ngOnDestroy() {
if (this.component !== null && this.component !== undefined) {
this.appRef.detachView(this.component.hostView);
this.component.destroy();
}
}
}
The custom field is now declared as a custom-tab-content component. The updated demo is available at creator-with-material-custom-tab_option2.zip.
User Issue: T14410 - Angular material is not working properly in Custom plugin tab ( Creator ) https://surveyjs.answerdesk.io/internal/ticket/details/T14410
https://github.com/surveyjs/survey-creator/assets/22372972/93c5ebb5-0d51-441c-b313-16bad9b4162e