How to Access codemirror text area value in Angula

2020-04-21 07:52发布

问题:

I am trying to link codemirror with Angular 2 (TypeScript) . Right now ,I am able to display CodeEditor using a codearea custom directive ,which dynamically loads a script file and Formats the text area .

I am not able to get the value ,the user types in the text area ,I have tried NgModel,value etc ,I think codemirror is removing the textarea and re inserting it again ,that might cause an error .

I have tried to use onchange and keyup event handlers ,but they are being repeatedly called when anything is entered in the text area .So that isnt usefull.

Here is the Code of code-Area Component :

import {Component, AfterViewChecked,AfterViewInit} from 'angular2/core';

@Component({
    selector: 'code-area',
    template: `
    <input [(ngModel)]="ic_code">
    <textarea [(ngModel)]="ic_code" id='problem2' name='problem2' rows='10' cols='80'>

    </textarea>
    <div>
    <textarea [(ngModel)]="ic_code" id='problem1' name='problem2' rows='10' cols='80'>
    int main(){

    }
    </textarea>
    </div>
    <button (click)="submit_clicked()">Submit</button>
    <input [(ngModel)]="ic_code">
    `
})
export class CodeArea implements AfterViewInit,AfterViewChecked{
    public ic_code;
    public ic_code2;
    public ic_codediv;
    constructor(){
        this.ic_code = "";
        System.import('app/applycodemirror')
            .then(refToLoadedScript => {
                applycodestyle();
            });
    }

    ngAfterViewInit(){
        console.log("AFter view init called in CodeArea");
    }
    ngAfterViewChecked(){

    }
    onChange(){
        //This is being repeatedly called
    }
    submit_clicked() {
        //I need the code here ,when user clicks on submit
    }
    onKey(event: any) {
        console.log(event.target.value+' ');
    }

}

Here is the external js file

function applycodestyle(){
      if(document.getElementById("problem1") != null){
        console.log("Problem 1 present");
        var cEditor = CodeMirror.fromTextArea(document.getElementById("problem1"), {
          lineNumbers: true,
          matchBrackets: true,
          mode: "text/x-csrc",
        });
      }else{
        console.log("Problem 1 null");
      }
}

回答1:

I use it a little bit differently but maybe it will help you. Basiaclly in ngAfterViewInit I create code mirror instance using elementRef:

this.cm = CodeMirror(this.elementRef.nativeElement, options);

then in the onChange event:

this.cm.on('change', (editor: CodeMirror.Editor) => {
  editor.getDoc().getValue();
});

If you don't want to use onChange, you can always get the value from code mirror instance, eg.

cmInstance.getEditor().getDoc().getValue()


回答2:

You can use ng2-codemirror

Install

npm install ng2-codemirror --save

Setup

systemjs.config.js

/**
 * System configuration for Angular samples
 * Adjust as necessary for your application needs.
 */
(function (global) {
    var data = {
        paths: {
            // paths serve as alias
            'npm:': '/node_modules/'
        },
        // map tells the System loader where to look for things
        map: {
            // our app is within the app folder
            app: '/Template/js/kpxl/app',

            // angular bundles
            '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
            '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
            '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
            '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
            '@angular/platform-browser-dynamic':
                'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
            '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
            '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
            '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',

            //Add these code mirror packages
            'ng2-codemirror': 'npm:ng2-codemirror',
            'codemirror': 'npm:codemirror',
        },
        // packages tells the System loader how to load when no filename and/or no extension
        packages: {
            codemirror: {
                main: 'lib/codemirror.js',
                defaultExtension: 'js'
            }
        }
    };
    data.packages['ng2-codemirror'] = { main: 'lib/index.js', defaultExtension: 'js' };
    System.config(data);
})(this);

Use Sample

Include CodeMirror css files in your page

<link href="/node_modules/codemirror/lib/codemirror.css" rel="stylesheet" />
<link href="/node_modules/codemirror/theme/ambiance.css" rel="stylesheet" />

Include CodemirrorModule in your main module :

import { CodemirrorModule } from 'ng2-codemirror';

@NgModule({
  // ... 
  imports:      [
    CodemirrorModule
  ],
  // ... 
})
export class AppModule { }

Use in your any Component.

import { Component } from 'angular2/core';

@Component({
  selector: 'sample',
  template: `
    <codemirror [(ngModel)]="code"
      [config]="{...}"
      (focus)="onFocus()"
      (blur)="onBlur()">
    </codemirror>
  `
})
export class Sample{
  constructor(){
    this.code = `// Some code...`;
  }
}