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

Added working output for initialization so that users can get the instance #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

rlodge
Copy link

@rlodge rlodge commented May 23, 2017

Fixes #17

@cmpilato
Copy link

cmpilato commented Jun 1, 2017

+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.

@rlodge
Copy link
Author

rlodge commented Jun 1, 2017

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();
  }

}

@cmpilato
Copy link

cmpilato commented Jun 1, 2017

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).

@cmpilato
Copy link

cmpilato commented Jun 1, 2017

...and it works! Thanks, @rlodge, for the inspiration!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants