Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

INT-2974: Support OnPush change detection #368

Merged
merged 9 commits into from
Apr 5, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Usage of RxJS deprecated operators. #INT-3274
### Added
- Support for Angular 15, 16 & 17. #INT-3274
- Suuport for the OnPush change detection strategy. #INT-2974
danoaky-tiny marked this conversation as resolved.
Show resolved Hide resolved
### Improved
- Updated Storybook to v8, as well as now using CSFv3 components. #INT-3274

Expand Down
12 changes: 12 additions & 0 deletions stories/Editor.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { EventBindingComponent } from './event-binding/EventBinding.component';
import { EventForwardingComponent } from './event-forwarding/EventForwarding.component';
import { FormControlComponent } from './form-control/FormControl.component';
import { FormWithOnPushComponent } from './form-with-on-push/form-with-on-push.component';
import { BlogComponent } from './formvalidation/FormValidation.component';
import { DisablingComponent } from './disable/Disable.component';
import { ViewQueryComponent } from './viewquery/Viewquery.component';
Expand Down Expand Up @@ -97,6 +98,17 @@ export const FormControlStory: StoryObj<EditorComponent> = {
}
};

export const FormStateStory: StoryObj<EditorComponent> = {
name: 'Form with on-push change detection',
render: () => ({
moduleMetadata: {
imports: [ ReactiveFormsModule, FormsModule ],
declarations: [ FormWithOnPushComponent ],
},
template: `<form-with-on-push apiKey="${apiKey}"/>`
}),
};

export const FormValidationStory: StoryObj<EditorComponent> = {
name: 'Form Validation',
render: () => ({
Expand Down
31 changes: 31 additions & 0 deletions stories/form-with-on-push/form-with-on-push.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-parameter-properties */
import {
Component,
ChangeDetectionStrategy,
Input,
} from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import type { EditorComponent } from '../../tinymce-angular-component/src/main/ts/public_api';

@Component({
selector: 'form-with-on-push',
templateUrl: './form-with-on-push.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FormWithOnPushComponent {
@Input() public apiKey = '';
public readonly initialValue = '';
public readonly init: EditorComponent['init'] = {
plugins: [ 'help' ],
};
public readonly form = new FormGroup({
tiny: new FormControl('', {
validators: Validators.compose([
Validators.required,
Validators.minLength(10)
]),
}),
regular: new FormControl(''),
});
}
24 changes: 24 additions & 0 deletions stories/form-with-on-push/form-with-on-push.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<form [formGroup]="form" style="display: flex; gap: 0.2em; flex-direction: column;">
<editor
formControlName="tiny"
plugins="table"
init="{ width: '200px', }"
/>
<br />
<label>
<span>Regular input</span>
<br />
<input type="text" formControlName="regular" />
</label>
<br />
<button type="reset" style="width: 200px">Reset form</button>
<button [disabled]="form.invalid" type="submit" style="width: 200px">Submit form</button>
</form>
<br />
<pre>
Pristine: {{ form.pristine }}
Touched: {{ form.touched }}
Dirty: {{ form.dirty }}
Valid: {{ form.valid }}
Data: {{ form.value | json }}
</pre>
22 changes: 20 additions & 2 deletions tinymce-angular-component/src/main/ts/editor/editor.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
/* eslint-disable @typescript-eslint/no-parameter-properties */
import { isPlatformBrowser, CommonModule } from '@angular/common';
import { AfterViewInit, Component, ElementRef, forwardRef, Inject, Input, NgZone, OnDestroy, PLATFORM_ID, InjectionToken, Optional } from '@angular/core';
import {
AfterViewInit,
Component,
ElementRef,
forwardRef,
Inject,
Input,
NgZone,
OnDestroy,
PLATFORM_ID,
InjectionToken,
Optional,
ChangeDetectorRef,
ChangeDetectionStrategy
} from '@angular/core';
import { FormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Subject, takeUntil } from 'rxjs';
import { getTinymce } from '../TinyMCE';
Expand All @@ -25,7 +39,8 @@ const EDITOR_COMPONENT_VALUE_ACCESSOR = {
styles: [ ':host { display: block; }' ],
providers: [ EDITOR_COMPONENT_VALUE_ACCESSOR ],
standalone: true,
imports: [ CommonModule, FormsModule ]
imports: [ CommonModule, FormsModule ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class EditorComponent extends Events implements AfterViewInit, ControlValueAccessor, OnDestroy {

Expand Down Expand Up @@ -77,6 +92,7 @@ export class EditorComponent extends Events implements AfterViewInit, ControlVal
public constructor(
elementRef: ElementRef,
ngZone: NgZone,
private cdRef: ChangeDetectorRef,
@Inject(PLATFORM_ID) private platformId: Object,
@Optional() @Inject(TINYMCE_SCRIPT_SRC) private tinymceScriptSrc?: string
) {
Expand Down Expand Up @@ -187,10 +203,12 @@ export class EditorComponent extends Events implements AfterViewInit, ControlVal

private initEditor(editor: TinyMCEEditor) {
listenTinyMCEEvent(editor, 'blur', this.destroy$).subscribe(() => {
this.cdRef.markForCheck();
this.ngZone.run(() => this.onTouchedCallback());
});

listenTinyMCEEvent(editor, this.modelEvents, this.destroy$).subscribe(() => {
this.cdRef.markForCheck();
this.ngZone.run(() => this.emitOnChange(editor));
});

Expand Down
Loading