Open rlodge opened 7 years ago
+1 for a change of this sort.
I'm upgrading an AngularJS app (which used ui-codemirror
) to Angular2. ui-codemirror
added a magic onLoad
callback function option which carried the CodeMirror editor instance, allowing folks to hook directly into the event system, manually refresh the editor, etc. In my situation, this is important for a number of reasons (one of which is that I need to distinguish between change
events that occur as the result of setValue
being called and those which don't -- something I can't do by merely hooking into ng2-codemirror's (change)
EventEmitter).
I would argue that if you provided a hook that gave access to the CodeMirror instance, you could drop the (focus)
, (blur)
, and (change)
hooks because those are easy enough to tap into via the editor instance itself.
I haven't seen any action on the PR or the underlying issue, but I've discovered it's also possible to subclass the component to get access. The below example uses a "settings service" that I'm using to allow a user to select a theme; all I need is to subscribe to the service's emitter and react by calling setOption, but you could do anything, including publishing the instance to your own emitter in the overridden method.
import {CodemirrorComponent} from "ng2-codemirror";
import {Component, forwardRef, OnDestroy} from "@angular/core";
import {NG_VALUE_ACCESSOR} from "@angular/forms";
import {SettingsService} from "../settings/settings.service";
import {Subscription} from "rxjs/Subscription";
//Make sure that the selector is DIFFERENT than the original component's.
@Component({
selector: 'themable-codemirror',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ThemableCodemirrorComponent),
multi: true
}
],
template: `<textarea #host></textarea>`,
})
export class ThemableCodemirrorComponent extends CodemirrorComponent implements OnDestroy {
subscription: Subscription = null;
constructor(private settingsService: SettingsService) {
super()
}
codemirrorInit(config: any): void {
super.codemirrorInit(config);
this.subscription = this.settingsService.emitter.subscribe((theme) => {
this.instance.setOption("theme", theme.classes.join(' '));
});
}
ngOnDestroy(): void {
if (this.subscription) {
this.subscription.unsubscribe();
}
super.ngOnDestroy();
}
}
I hadn't considered the subclassing idea (still pretty new to TypeScript). I'm taking a crack right now at a simple subclass that adds an @Output onInit: EventEmitter
interface (like the PR carries).
...and it works! Thanks, @rlodge, for the inspiration!
Fixes #17