Написание директивы для существующего объекта javascript угловым способом

Я работаю над созданием директивы Angular, которая инкапсулирует viewer.js функциональность для проекта pdf.js, потому что мне очень нравится, как выглядит их средство просмотра, но я хотел бы иметь возможность передавать переменные из моих собственных привязок Angular.

Сейчас существует два проекта в стиле angular в формате pdf, например проект Sayanee (https://github.com/sayanee/angularjs-pdf), который, похоже, в основном предоставляет базовую функциональность по адресу https://github.com/mozilla/pdf.js/blob/master/examples/text-selection/.js/minimal.js и проект Anrennmair на https://github.com/akrennmair/ng-pdfviewer

Эти программы просмотра pdf действительно выглядят не очень хорошо, и мне нравится, как программа просмотра pdf.js показывает страницу за просмотром страницы и позволяет легко их прокручивать. Мне не нужны все функции печати, закладок, вложений, сохранения, открытия и т. Д., Чтобы сэкономить хотя бы часть работы, но мой вопрос таков:

Как мне написать эту программу просмотра в виде директивы? В частности, в ответе на предыдущий вопрос респондент сказал, что первый проект GitHub был плохо спроектирован с точки зрения angular- точка зрения. Как правильно это сделать? Я бы предпочел написать это хорошо в первый раз в соответствии с некоторыми передовыми практиками, но я не смог найти ничего ясного в отношении того, что эти практики будут в этой области.


person Whit Waldo    schedule 29.06.2014    source источник


Ответы (2)


В основном вам нужно быть ограниченным элементом директивы. Используйте шаблон, чтобы добавить теги canvas и div. Затем вызовите их в функции link, чтобы отобразить PDF-файл.

Вы можете сделать еще один шаг и обернуть функции PDFJS и render и load в службу angular, а затем вставить это в директиву. Таким образом, методы загрузки и рендеринга будут находиться в службе, а директива просто настроит шаблон и вызовет их.

Разметка:

<pdf-viewer pdf-path="pathToYourPdf"></pdf-viewer>

Директива: это не на самом деле функциональная директива, но она должна дать вам общее представление о том, как достичь того, что вы ищете.

angular.module('myApp', [])
  .directive('pdfViewer', [

    function() {
      return {
        template: '<canvas></canvas><div></div>',
        replace: true,
        restrict: 'E',
        scope: {
          pdfPath: '='
        },
        link: function postLink(scope, iElement, iAttrs) {
          scope.pdfPath = iAttrs.$eval(pdfPath);

          scope.pdf = PDFJS.getDocument(scope.pdfPath);

          scope.pdf
            .then(renderPdf);

          var renderPdf = function() {
            service.pdf.getPage(1)
              .then(renderPage);
          };

          var renderPage = function(page) {
            var viewport = page.getViewport(scale);
            var canvas = iElement.find('canvas')[0];
            // Set the canvas height and width to the height and width of the viewport
            var context = canvas.getContext("2d");

            // The following few lines of code set up scaling on the context if we are on a HiDPI display
            var outputScale = getOutputScale(context);
            canvas.width = (Math.floor(viewport.width) * outputScale.sx) | 0;
            canvas.height = (Math.floor(viewport.height) * outputScale.sy) | 0;
            canvas.style.width = Math.floor(viewport.width) + 'px';
            canvas.style.height = Math.floor(viewport.height) + 'px';

            // Append the canvas to the pdf container div
            var $pdfContainer = iElement;
            iElement.css("height", canvas.style.height)
              .css("width", canvas.style.width);

            var canvasOffset = canvas.offset();

            var textLayerDiv = iElement.find('div')[0];

            textLayerDiv
              .addClass("textLayer")
              .css("height", canvas.style.height)
              .css("width", canvas.style.width)
              .offset({
                top: canvasOffset.top,
                left: canvasOffset.left
              });

            context._scaleX = outputScale.sx;
            context._scaleY = outputScale.sy;
            if (outputScale.scaled) {
              context.scale(outputScale.sx, outputScale.sy);
            }

            page.getTextContent()
              .then(function(textContent) {
                var textLayer = new TextLayerBuilder({
                  textLayerDiv: textLayerDiv,
                  viewport: viewport,
                  pageIndex: 0
                });

                textLayer.setTextContent(textContent);

                var renderContext = {
                  canvasContext: context,
                  viewport: viewport
                };

                page.render(renderContext);
              });
          };
        }
      };
    }
  ]);
person winkerVSbecks    schedule 29.06.2014
comment
+1, хороший ответ, должен был помочь OP начать работу - полезно для меня - спасибо! Я должен сказать - меня беспокоит, когда люди тратят время, чтобы ответить на вопрос, а ОП не требует времени, чтобы принять или даже проголосовать! - person Drammy; 18.07.2014
comment
К сожалению, хотя я, несомненно, получил уведомление об этом в то время, я действительно не забыл ответить. Мои извенения. В итоге я обнаружил, что код, доступный по адресу github.com/jviereck/pdfListView, больше соответствует тому, чем я был ищу (в том смысле, что он не представлен как слайд-шоу, а скорее как прокручиваемый документ PDF, как он появляется в PDF.js). - person Whit Waldo; 09.02.2015

Как упоминалось в одном из комментариев, я обнаружил, что информация, доступная по адресу https://github.com/jviereck/pdfListView был весьма полезен при определении того, как это сделать в контексте Angular в средстве просмотра, которое также выглядело оптимальным.

person Whit Waldo    schedule 09.02.2015