2016-05-07 22 views
1

現在、私はCodeMirrorエディタをプロジェクトに、Angular2プロジェクトをより正確に追加しようとしています。しかし、私はそれをやるのに困っている。私のエディタのインスタンス化は正しく動作していないようです。私はこのような何かを、CodeMirrorとAngular2(typescript)の統合

editor.component.ts私のindex.htmlファイル

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> 

:私のコードは次のようです:

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

私はこの方法で自分のアプリをブートストラップしていますが、問題の原因はどこにあるのかはわかりません。

boot.ts

import {bootstrap} from 'angular2/platform/browser' 
import {AppComponent} from './app.component' 

bootstrap(AppComponent); 

私がしようとすると、アプリケーションを実行して、Firefoxは私に語ったこと'EXCEPTION:エディタのインスタンス化中にエラーが発生しました!'、その'オリジナルの例外:TypeError:textareaがnull'も同様です。何が起こっているか、どのようにこれを修正するかについての任意のアイデア?

すべての私の感謝の気持ち

答えて

0

の問題点は、BrowserDomAdapterを通じて正しいDOM要素を取得していないということかもしれません(私はそれがHTMLルートからではなく、現在のコンポーネントのコンテキストからテキストエリアを検索します推測し、それは知られていません)、テキストボックスはnullになります。ここで

は(codemirrorをインスタンス化するために、例えば)は、テンプレート内の要素への参照を取得し、コンポーネントのコード内であることを使用する方法について説明し、いくつかの方法があります。Angular2: What is the best way to get a reference of a template element

2

は、あなたの助けのためにどうもありがとうございます、私はあなたのリンクで与えられたいくつかのヒントに従って、指示を使ってそれを作った。私はそれ以降もいくつかの問題を経験しましたが、大したことはありませんでした。コンポーネント経由でリンクタグを読み込むことができなかっただけです。あなたがこれを読んで、同様の問題に遭遇している場合は、ここに私の解決策だった:

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

そして最後に、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> 
+0

はありがとうございました!将来の視聴者のために、 'ディレクティブ 'が' component'から削除されました。以下を参照してください:https://stackoverflow.com/a/39410642/5487673 – jonathana

2

angular 2 documentationとしてElementRefを使用しないでください。特に、あなたは避けなければならない:

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.

使用Renderer2代わりに:とても役に立ちました

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