Google pagedown AngularJS directive

后端 未结 4 1630
清歌不尽
清歌不尽 2020-12-23 17:50

See bottom of question for an improved solution to this problem

I have been trying for some time now to get a directive for the pagedown

相关标签:
4条回答
  • 2020-12-23 17:52

    It might not be the answer, but all the problem occurs when you start using Markdown.Editor which does not gives you a lot of benefits.

    Of course, you need to use it for markdown editor beginners, but when use markdown, they are already not beginners anyway(I might be wrong).

    What I approached to this problem was to make fully working version of this without using editor.

    It has preview also.

    It's also very simple.

    https://github.com/allenhwkim/wiki

    ---- edit ----
    removed
    ---- edit ----
    removed
    ---- edit ----

    To provide a fully working editor, after few hours of trial and asking questions, the following is the simplest I can get. This does require any $watch nor $formatters. It just wraps the given element with all attributes given by the textarea.

    http://plnkr.co/edit/jeZ5EdLwOfwo6HzcTAOR?p=preview

    app.directive('pagedownEditor', function($compile, $timeout) {
      var num=0;
      return {
        priority: 1001, //higher than ng-repeat, 1000
        link: function(scope, el, attrs) {
          var uniqNum = scope.$index || num++;
          var wmdPanel = document.createElement('div');
          wmdPanel.className = "wmd-panel";
          var wmdButtonBar = document.createElement('div');
          wmdButtonBar.id = 'wmd-button-bar-'+uniqNum;
          wmdPanel.appendChild(wmdButtonBar);
          el.wrap(wmdPanel); // el is ng-repeat comment, it takes tim
    
          var converter = Markdown.getSanitizingConverter();
          var editor = new Markdown.Editor(converter, "-"+uniqNum);
          $timeout(function() {
            wmdPanel.querySelector('textarea').id = 'wmd-input-'+uniqNum;
            wmdPanel.querySelector('textarea').className += ' wmd-input';
            wmdPanel.insertAdjacentHTML('afterend', '<div id="wmd-preview-'+uniqNum+'" '
              +'class="pagedown-preview wmd-panel wmd-preview">');
            editor.run()
          }, 50);
        }
      };
    
    0 讨论(0)
  • 2020-12-23 18:02

    You can change this:

    scope.$watch(attrs.ngModel, function () {
    var val = scope.$eval(attrs.ngModel);
    

    For this:

    scope.$watch(attrs.ngModel, function(newValue, oldValue) {
      var val = newValue;
    });
    

    Additionally can try commenting this code out:

    if (val !== undefined) {
        $wmdInput.val(val);
        ...    
    

    }

    I think it may be associated with the odd behavior.

    0 讨论(0)
  • 2020-12-23 18:02

    Demo: http://plnkr.co/edit/FyywJS?p=preview

    Summary

    1. I removed keyup and added a hook on onPreviewRefresh to ensure clicking on toolbar will properly update ng-model.

    2. Functions on $rootScope will demonstrate the ability to update ng-model from outside of pagedown.

    3. save functionality purely depends on your choice, since you can access ng-model anywhere now.

    0 讨论(0)
  • 2020-12-23 18:17

    Here is a working link:

    http://cssdeck.com/labs/qebukp9k

    UPDATE

    • I made some optimizations.
    • I use ngModel.$formatters ! no need for another $watch.
    • I use $timeout and then scope.$apply to avoid $digest in progress errors.

    Angular.js & Performance

    • If you hit performance maybe your application is using too many $watch / $on.
    • In my experience, using 3rd-party libraries can cause all sort of non efficient / memory leaking behavior, mostly because it was not implemented with angular / SPA in mind.
    • I was able to do some smart integration for some libraries but some just don't fit well to angular's world.
    • If your application must show 1000+ questions you should probably start with writing your custom repeater, and prefer dynamic DOM insertions.
    • Angular.js will not perform well with tons of data bindings unless you are willing to write some smart lower level stuff (It's actually fun when you know how!).
    • Again, prefer pagination! As Misko Hevery says: "You can't really show more than about 2000 pieces of information to a human on a single page. Anything more than that is really bad UI, and humans can't process this anyway".
    • Read this: How does data binding work in AngularJS?
    • I'm more than happy to help you, but First let me show the code (contact me)..

    Solution:

    var app = angular.module('App', []);
    
    app.directive('pagedownAdmin', function ($compile, $timeout) {
        var nextId = 0;
        var converter = Markdown.getSanitizingConverter();
        converter.hooks.chain("preBlockGamut", function (text, rbg) {
            return text.replace(/^ {0,3}""" *\n((?:.*?\n)+?) {0,3}""" *$/gm, function (whole, inner) {
                return "<blockquote>" + rbg(inner) + "</blockquote>\n";
            });
        });
    
        return {
            require: 'ngModel',
            replace: true,
            template: '<div class="pagedown-bootstrap-editor"></div>',
            link: function (scope, iElement, attrs, ngModel) {
    
                var editorUniqueId;
    
                if (attrs.id == null) {
                    editorUniqueId = nextId++;
                } else {
                    editorUniqueId = attrs.id;
                }
    
                var newElement = $compile(
                    '<div>' +
                       '<div class="wmd-panel">' +
                          '<div id="wmd-button-bar-' + editorUniqueId + '"></div>' +
                          '<textarea class="wmd-input" id="wmd-input-' + editorUniqueId + '">' +
                          '</textarea>' +
                       '</div>' +
                       '<div id="wmd-preview-' + editorUniqueId + '" class="pagedown-preview wmd-panel wmd-preview"></div>' +
                    '</div>')(scope);
    
                iElement.html(newElement);
    
                var help = function () {
                    alert("There is no help");
                }
    
                var editor = new Markdown.Editor(converter, "-" + editorUniqueId, {
                    handler: help
                });
    
                var $wmdInput = iElement.find('#wmd-input-' + editorUniqueId);
    
                var init = false;
    
                editor.hooks.chain("onPreviewRefresh", function () {
                  var val = $wmdInput.val();
                  if (init && val !== ngModel.$modelValue ) {
                    $timeout(function(){
                      scope.$apply(function(){
                        ngModel.$setViewValue(val);
                        ngModel.$render();
                      });
                    });
                  }              
                });
    
                ngModel.$formatters.push(function(value){
                  init = true;
                  $wmdInput.val(value);
                  editor.refreshPreview();
                  return value;
                });
    
                editor.run();
            }
        }
    });
    
    0 讨论(0)
提交回复
热议问题