Use 2 ui-codemirrors in 1 controller

I code a very basic playground using AngularJS and ui-codemirror . Here is the code ( JSBin ).

 <html> <head> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.css"> <link rel="stylesheet" href="https://codemirror.net/lib/codemirror.css"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script> <script src="https://codemirror.net/lib/codemirror.js"></script> <script src="https://codemirror.net/addon/edit/matchbrackets.js"></script> <script src="https://codemirror.net/mode/htmlmixed/htmlmixed.js"></script> <script src="https://codemirror.net/mode/xml/xml.js"></script> <script src="https://codemirror.net/mode/javascript/javascript.js"></script> <script src="https://codemirror.net/mode/css/css.js"></script> <script src="https://codemirror.net/mode/clike/clike.js"></script> <script src="https://codemirror.net/mode/php/php.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.js"></script> </head> <body> <div ng-app="myApp"> <div ng-controller="codeCtrl"> HTML:<br> <textarea ui-codemirror ng-model="html"></textarea> <br>CSS:<br> <textarea ui-codemirror ng-model="css"></textarea> </div> Output: <section id="output"> <iframe></iframe> </section> </div> </body> </html> 

JavaScript:

 var myApp = angular.module('myApp', ['ui']); myApp.value('ui.config', { codemirror: { mode: 'text/x-php', lineNumbers: true, matchBrackets: true, } }); function codeCtrl($scope, codeService) { $scope.html = '<body>default</body>'; $scope.css = "body {color: red}"; $scope.$watch('html', function () { codeService.render($scope.html, $scope.css); }, true); $scope.$watch('css', function () { codeService.render($scope.html, $scope.css); }, true); } myApp.service('codeService', function () { this.render = function (html, css) { source = "<html><head><style>" + css + "</style></head>" + html +"</html>"; var iframe = document.querySelector('#output iframe'), iframe_doc = iframe.contentDocument; iframe_doc.open(); iframe_doc.write(source); iframe_doc.close(); } }) 

The above code works, but the problem is that it applies the same ui.config to 2 ui-codemirror . Does anyone know how to apply html mode to the first ui-codemirror and mode css to the second ui-codemirror ?

Also, how could I set the height (or rows ) and width (or cols ) in a ui-codemirror ?

+3
angularjs iframe angular-ui codemirror ui-codemirror
source share
2 answers

Controller:

 function codeCtrl($scope, codeService) { $scope.editorOptions1 = {mode: 'text/html', lineNumbers: false, matchBrackets: true}; $scope.editorOptions2 = {mode: 'text/css', lineNumbers: true, matchBrackets: true}; $scope.html = '<body>default</body>'; $scope.css = "body {color: red}"; $scope.$watch('html', function () { codeService.render($scope.html, $scope.css); }, true); $scope.$watch('css', function () { codeService.render($scope.html, $scope.css); }, true); } 

Html:

 <div ng-controller="codeCtrl"> HTML:<br> <textarea ui-codemirror="editorOptions1" ng-model="html"></textarea> <br>CSS:<br> <textarea ui-codemirror="editorOptions2" ng-model="css"></textarea> </div> 
+2
source share

Since you are dealing with two separate text areas that have different roles (or imagine if they were larger), it makes sense to define separate directives for them, each of which accepts a different configuration object. I created JSBin , which shows one possible approach, through the factory directive, which can be used to create different "mirrors".

 angular.module('codeMirrorApp') .factory('CodeMirrorFactory', ['$parse', function($parse) { return { createDirective: function(config) { var configString = JSON.stringify(config); return { scope: true, restrict: 'E', template: '<textarea ui-codemirror=' + configString + ' ng-model="content"></textarea>', controller: ['$scope', '$attrs', function($scope, $attrs) { var handler = $parse($attrs.handler); $scope.$watch('content', function(value) { handler($scope, { content: value }); }); }] }; } }; } ]); 

I intentionally use handlers provided by the parent controller instead of bindings to the parent scope, as this makes things more understandable even when viewing HTML markup.

Controller:

 angular.module('codeMirrorApp') .controller('MirrorsController', ['RenderMirrors', function(RenderMirrors) { var ctrl = this, html, css; ctrl.handleHtml = function(htmlString) { html = htmlString; RenderMirrors.render(html, css); }; ctrl.handleCss = function(cssString) { css = cssString; RenderMirrors.render(html, css); }; } ]); 

Markup:

 <div ng-app="codeMirrorApp"> <div ng-controller="MirrorsController as ctrl"> HTML:<br> <html-code-mirror handler="ctrl.handleHtml(content)"></html-code-mirror> <br>CSS:<br> <css-code-mirror handler="ctrl.handleCss(content)"></css-code-mirror> </div> Output: <section id="output"> <iframe></iframe> </section> </div> 

Hope this helps.

+2
source share

All Articles