1

I want to make an editor of files. By the following code (JSBin), we list all the file names on the left hand, and their body on the right hand. I use ui-codemirror to style the body of the files.

However, when we click on the file names and switch from one to another, from time to time, we could see the quick flick from a textarea to a codemirror frame, which is not a good experience for an editor.

Does anyone have a solution to avoid the flick? Addtionally, is it a good direction to make an editor by angularJS and ui-codemirror?

<html ng-app="flapperNews">
<head>
  <link rel="stylesheet" href="https://codemirror.net/lib/codemirror.css">
  <script src="https://code.jquery.com/jquery.min.js"></script>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.2/angular-ui-router.js"></script>
  <script src="https://codemirror.net/lib/codemirror.js"></script>
  <script src="https://codemirror.net/mode/xml/xml.js"></script>
  <script src="https://codemirror.net/mode/htmlmixed/htmlmixed.js"></script>
  <script src="https://codemirror.net/mode/javascript/javascript.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.11.0/ui-bootstrap-tpls.js"></script>

  <script>
    var app = angular.module('flapperNews', ['ui', 'ui.router']);

    app.config(['$stateProvider', function ($stateProvider) {
      $stateProvider
        .state('file', {
          template: '<textarea ui-codemirror="editorOptionsHTML" ng-model="file.body"></textarea>',
          controller: 'FileCtrl',
          params: { name: null }
        })
    }]);

    app.controller('MainCtrl', ['$scope', '$state', function ($scope, $state) {
      $scope.files = [
        { name: "index.html", body: "<html><body>index.html</body></html>" },
        { name: "index.js", body: "the body of index.js" },
        { name: "test.html", body: "the body of test.html" }];
    }]);

    app.controller('FileCtrl', ['$scope', '$stateParams', function ($scope, $stateParams) {
      $scope.file = $scope.files.find(function (file) { return file.name === $stateParams.name });
      $scope.editorOptionsHTML = { mode: 'text/html', lineNumbers: true, matchBrackets: true };
    }]);
  </script>
</head>

<body ng-controller="MainCtrl">
  <div class="row">
    <div class="col-sm-3 col-md-3 col-xl-3 col-lg-3">
      <div ng-repeat="file in files track by $index">
        <a ui-sref="file({name: file.name})">{{file.name}}</a>
      </div>
    </div>
    <div class="col-sm-9 col-md-9 col-xl-9 col-lg-9">
      <ui-view></ui-view>
    </div>
  </div>
</body>

</html>
SoftTimur
  • 5,630
  • 38
  • 140
  • 292

2 Answers2

1

Every time you click on the link, it is creating new editor, which is an expense operation.

The best approach is to create one editor and load the content on every click.

so I removed the ui-router linking (ui-sref) and related controllers

<script>
 var app = angular.module('flapperNews', ['ui', 'ui.router']);

  app.controller('MainCtrl', ['$scope', '$state', function ($scope, $state) {
   $scope.files = [
    { name: "index.html", body: "<html><body>index.html</body></html>" },
    { name: "index.js", body: "the body of index.js" },
    { name: "test.html", body: "the body of test.html" }];

   $scope.editorOptionsHTML = { mode: 'text/html', lineNumbers: true, matchBrackets: true };


  // for every click event it will load the content
   $scope.go=function(file){
     $scope.file=file;
   }
  }]);

and the body

<body ng-controller="MainCtrl">
  <div class="row">
    <div class="col-sm-3 col-md-3 col-xl-3 col-lg-3">
      <div ng-repeat="file in files track by $index">
        <a ng-click="go(file)">{{file.name}}</a>
      </div>
    </div>
    <div class="col-sm-9 col-md-9 col-xl-9 col-lg-9">
      <textarea ui-codemirror="editorOptionsHTML" ng-model="file.body"></textarea>
    </div>
  </div>
</body>

Example : JSBin

Pavan Kumar Jorrigala
  • 3,085
  • 16
  • 27
  • I don't know why your codepen does not work... Here is my [JSBin](https://jsbin.com/tiducocevu/1/edit?html,output) with the same idea... – SoftTimur Feb 19 '17 at 14:47
0

you could avoid the flick by adding hide class to textarea like the following code ( jsbin )

template: '<textarea class="hide" ui-codemirror="editorOptionsHTML" ng-model="file.body"></textarea>',
fingerpich
  • 8,500
  • 2
  • 22
  • 32
  • Thanks for your answer... It is better now, we could not see flick **from textarea to ui-codemirror** anymore. However, we could still see flick **from time to time** when we switch files (even though between two files with the same content), I tested it in Chrome and Safari. Do you have any solution for this? – SoftTimur Feb 18 '17 at 21:29
  • I realised that changing external links like [here](http://stackoverflow.com/a/42316338/702977) solved the problem... – SoftTimur Feb 19 '17 at 15:51