Estoy codificando un patio de recreo muy muy básico. Por alguna razón, necesito incrustar el panel html dentro de una aplicación AngularJS.

En esta versión, puse un oyente de cambio JQuery en el panel CSS , y aplicó CodeMirror al área de texto. Y funcionó.

Me sentí incómodo por tener un detector de eventos JQuery dentro de una aplicación AngularJS, así que decidí vincular el panel CSS a la aplicación AngularJS e hice esta versión. Pero ahora, el problema es que el código CodeMirror (que comento a continuación) ya no funciona:

Html:

<body>
  <div ng-app="myApp" ng-controller="myCtrl">
    HTML:<br>
    <textarea rows=10 cols=40 ng-model="area1">html body area</textarea>
    <br>CSS:<br>
    <textarea id="css" rows=10 cols=40 ng-model="css"></textarea>
  </div>
  Output:
  <section id="output">
    <iframe></iframe>
  </section>
</body>

Javascript:

var app = angular.module('myApp', []);

app.controller('myCtrl', function($scope) {
    $scope.area1 = "<body>default</body>";  
    $scope.$watch('area1', function (json) {
      render();
    }, true);

    $scope.css="body {color: red}";
    $scope.$watch('css', function (json) {
      // CodeMirror does not work anymore
      // var cm_opt = { mode: 'css', gutter: true, lineNumbers: false };
      // var css_box = document.getElementById("css");
      // var css_editor = CodeMirror.fromTextArea(css_box, cm_opt);
      render();
    }, true);

    function render () {
      var source = "<html><head><style>" + $scope.css + "</style></head>" + 
                   $scope.area1 +"</html>";

      var iframe = document.querySelector('#output iframe'),
          iframe_doc = iframe.contentDocument;

      iframe_doc.open();
      iframe_doc.write(source);
      iframe_doc.close();
    }
 });

¿Alguien sabe cómo hacer que CodeMirror funcione aquí?

Además, ¿es realmente una mala idea usar oyentes de eventos JQuery dentro de una aplicación AngularJS? ¿Cuál es la mejor estructura para codificar este patio de recreo que usa AngularJS + CodeMirror?

Editar 1: encontré este hilo, luego hice una directiva codeMirror, no funciona bien. DevTools me muestra un error TypeError: textarea.getAttribute is not a function en CodeMirror.fromTextArea(...).

7
user6330767 27 dic. 2016 a las 15:32

3 respuestas

La mejor respuesta

Here Agregué el espejo Demo for Code en angularjs. Espero que te ayude...

Aquí Demo

2
Suresh B 29 dic. 2016 a las 13:24

Respuesta para resolver el segundo intento de OP

En la función link de la directiva, está utilizando el parámetro elem como un elemento HTML puro (que se espera por codemirror), pero angular lo proporciona como un elemento envuelto en JQLite, por lo que básicamente solo necesita obtener el Elemento HTML de él y proporcionar a codemirror, entonces funcionará:

var editor = CodeMirror.fromTextArea(elm[0], cm_opt);

(nota elem[0] en lugar de elem)

En AngularJS no es una mala práctica usar directivas para ajustar la lógica basada en JQuery para hacer componentes que se basen en otras tecnologías como el espejo de código. En algunos casos, puede hacerlo usted mismo, pero también puede usar bibliotecas de terceros ya construidas como se menciona en las otras respuestas.

Hagas lo que hagas, asegúrate de encapsular bien la lógica no angular, haciendo uso de directivas y servicios.

Espero que esto ayude.

1
Ovidiu Dolha 5 ene. 2017 a las 10:34

Puede usar

Directiva de UI.Codemirror

0
Sebri Zouhaier 5 ene. 2017 a las 10:23