I'm currently working on adding a CodeMirror editor to a project, an Angular2 project more precisely. But Im' having trouble doing it. The instantiation of my editor doesn't seem to work correctly. My code is the following:
editor.component.ts
import {Component} from 'angular2/core'
import {BrowserDomAdapter} from 'angular2/platform/browser'
declare var CodeMirror: any;
@Component({
selector: 'editor',
templateUrl: './meang2app/partials/editor.html'
})
export class Editor{
dom: BrowserDomAdapter;
editor: any;
constructor(){
this.dom = new BrowserDomAdapter();
this.editor = new CodeMirror.fromTextArea(this.dom.query("textarea"), {lineNumbers: true, mode: {name: "javascript", globalVars: true}});
}
}
editor.html
<textarea id="code" name="code">
<!-- Where a CodeMirror instance should be rendered -->
</textarea>
In my index.html file, I do something like this:
<html>
<head>
<title>Angular 2</title>
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="codemirror/lib/codemirror.js"></script>
<script src="codemirror/addon/hint/show-hint.js"></script>
<script src="codemirror/addon/hint/javascript-hint.js"></script>
<script src="codemirror/mode/javascript/javascript.js"></script>
<script>
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('app/dist/boot')
.then(null, console.error.bind(console));
</script>
</head>
<body>
<app>Loading</app>
</body>
</html>
I'm bootstrapping my app this way, but I don't think that's where the issue comes from.
boot.ts
import {bootstrap} from 'angular2/platform/browser'
import {AppComponent} from './app.component'
bootstrap(AppComponent);
When I try and run the app, firefox tells me that 'EXCEPTION: Error during instantiation of Editor!.', and that 'ORIGINAL EXCEPTION: TypeError: textarea is null' as well. Any idea about what's going on, and how to fix this?
With all my gratitude
Thank you so much for your help, I followed some of the tips given in your link and made it by using a directive. I went through some issues after that too, but no big deal: I just didn't know loading a link tag via a component wasn't possible. If you're reading this and encountered with a similar problem, here was my solution:
editor.component.ts
import {Component, ElementRef} from 'angular2/core'
import {EditorDirective} from './editor.directive'
@Component({
selector: 'editor',
template: `
<textarea editor id="code" name="code">
// Some content
</textarea>
`,
directives: [EditorDirective]
})
export class EditorComponent{
constructor(){}
}
editor.directive.ts
import {Directive, ElementRef, Renderer} from 'angular2/core'
declare var CodeMirror: any;
@Directive({
selector: '[editor]'
})
export class EditorDirective {
editor: any;
constructor(public element: ElementRef, public renderer: Renderer){
this.editor = new CodeMirror.fromTextArea(element.nativeElement, {lineNumbers: true, mode: {name: "javascript", globalVars: true}});
}
}
And to finish with, index.html:
<html>
<head>
<title>Angular 2 and CodeMirror</title>
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="codemirror-5.14.2/lib/codemirror.js"></script>
<script src="codemirror-5.14.2/addon/hint/show-hint.js"></script>
<script src="codemirror-5.14.2/addon/hint/javascript-hint.js"></script>
<script src="codemirror-5.14.2/mode/javascript/javascript.js"></script>
<script src="codemirror-5.14.2/mode/markdown/markdown.js"></script>
<link rel=stylesheet href="codemirror-5.14.2/doc/docs.css">
<link rel="stylesheet" href="codemirror-5.14.2/lib/codemirror.css">
<link rel="stylesheet" href="codemirror-5.14.2/addon/hint/show-hint.css">
<script>
System.config({
packages: {
meang2app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('meang2app/dist/editor.component')
.then(null, console.error.bind(console));
</script>
</head>
<body>
<app>Loading</app>
</body>
</html>
You should refrain from using ElementRef as per angular 2 documentation. Particularly, you should avoid:
tight coupling between your application and rendering layers which will make it impossible to separate the two and deploy your application into a web worker.
Use Renderer2 instead:
editor.directive.ts
@Directive({
selector: '[editor]'
})
export default class EditorDirective {
editor: any;
constructor(private _renderer: Renderer) {}
ngAfterViewInit() {
this.editor = CodeMirror.fromTextArea(
this._renderer.selectRootElement('[editor]'),
{
lineNumbers: true,
mode: {name: "javascript", globalVars: true}
}
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With