Подтвердить что ты не робот

Директива Google pagedown AngularJS

См. нижнюю часть вопроса для улучшения решения этой проблемы.

Я пытаюсь в течение некоторого времени получить директиву для работы pagedown. Это тот же самый редактор, который используется stackoverflow. Stackoverflow делает этот код доступным здесь:

https://code.google.com/p/pagedown/

В Интернете есть несколько версий, но никто не работает хорошо. Мне нужна та, которая появится со всеми кнопками редактора, такими как stackoverflow, как при кодировании inline, так и в том случае, когда она встроена как часть ngRepeat.

Я хотел бы, чтобы эта директива работала, когда она закодирована inline, а также внутри ng-repeat, используя Angular версию 1.2.7. Необходимо, чтобы при изменении данных модели директива должна обновлять представления pagedown, чтобы показать новые вопросы и ответы. Когда пользователь изменяет область редактирования pagedown, директива должна иметь возможность обновлять модель. Когда пользователь нажимает [save], данные модели должны быть сохранены в базе данных (или, по крайней мере, на другом объекте, чтобы подтвердить, что это сработало).

Директива должна иметь возможность реагировать на изменения в модели, а также сохранять ее необработанные данные в модели при нажатии клавиши или при нажатии кнопки "change" в редактируемой панели. Вот что я до сих пор. Обратите внимание, что эта версия не имеет $wmdInput.on('change', но это начало для того, что необходимо.

Самое главное, я хотел бы, чтобы это работало с версией 1.2.7 из Angular и jQuery 2.0.3. Обратите внимание, что я обнаружил различия с моими не- рабочий код между версиями 1.2.2 и 1.2.7. Я думаю, что лучше всего, если какое-либо решение будет работать для последней версии (1.2.7).

Обновление

Я теперь эту директиву, которая проще и решает некоторые недавние проблемы У меня был контент, который не показывался. Я очень рекомендую использовать эта директива, основанная на принятом ответе плюс несколько улучшения: https://github.com/kennyki/angular-pagedown

4b9b3361

Ответ 1

Вот рабочая ссылка:

http://cssdeck.com/labs/qebukp9k

UPDATE

  • Я сделал некоторые оптимизации.
  • Я использую ngModel. $formatters! нет необходимости в других часах $.
  • Я использую $timeout, а затем область. $применяются, чтобы избежать ошибок $digest.

Angular.js и производительность

  • Если вы достигли производительности, возможно, ваше приложение использует слишком много $watch/$on.
  • По моему опыту использование сторонних библиотек может вызвать всевозможные неэффективные/утечки памяти, в основном потому, что он не был реализован с учетом angular/SPA.
  • Я смог сделать некоторую интеллектуальную интеграцию для некоторых библиотек, но некоторые просто не подходят для мира angular.
  • Если ваше приложение должно показывать более 1000 вопросов, вы, вероятно, должны начать писать свой собственный ретранслятор и предпочитаете динамические вставки DOM.
  • Angular.js не будет хорошо работать с множеством привязок данных, если вы не захотите написать какой-нибудь умный материал нижнего уровня (это действительно весело, когда вы знаете, как!).
  • Опять же, предпочитайте разбиение на страницы! Как говорит Мишко Хевери: "На самом деле вы не можете показать больше, чем около 2000 единиц информации человеку на одной странице. Что-то большее, чем это действительно плохой пользовательский интерфейс, и люди все равно не могут его обработать".
  • Прочтите следующее: Как работает привязка данных в AngularJS?
  • Я рад помочь вам, но сначала позвольте мне показать код (свяжитесь со мной)..

Решение:

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();
        }
    }
});

Ответ 2

Это может быть не ответ, но вся проблема возникает, когда вы начинаете использовать Markdown.Editor, который не дает вам много преимуществ.

Конечно, вам нужно использовать его для начинающих редактора markdown, но при использовании уценки они уже не являются новичками (я могу ошибаться).

То, к чему я подошел, состояло в том, чтобы сделать полностью рабочую версию этого без использования редактора.

Он также имеет предварительный просмотр.

Это тоже очень просто.

https://github.com/allenhwkim/wiki

---- править ----
удалены
---- править ----
удалены
---- править ----

Чтобы предоставить полностью работоспособный редактор, после нескольких часов пробного периода и задавая вопросы, самое простое, что я могу получить. Для этого требуются любые $watch или $formatters. Он просто обертывает данный элемент со всеми атрибутами, указанными в текстовом поле.

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);
    }
  };

Ответ 3

Вы можете изменить это:

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

Для этого:

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

Дополнительно можно попробовать прокомментировать этот код:

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

}

Я думаю, что это может быть связано с нечетным поведением.

Ответ 4

Демо: http://plnkr.co/edit/FyywJS?p=preview

Резюме

  • Я удалил keyup и добавил крючок на onPreviewRefresh, чтобы убедиться, что щелчок на панели инструментов будет правильно обновляться ng-model.

  • Функции в $rootScope продемонстрируют возможность обновления ng-model извне pagedown.

  • сохранить функциональность зависит только от вашего выбора, так как теперь вы можете получить доступ к ng-model где-либо сейчас.