如何延迟指令的运行逻辑,直到 ui-route 得到解决? [英] How to delay running logic for directive until ui-route is resolved?

查看:20
本文介绍了如何延迟指令的运行逻辑,直到 ui-route 得到解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 ui-router 的 AngularJS.我正在尝试使用 https://github.com/sayanee/angularjs-pdf.我必须对给出的示例进行一些更改,因为我没有立即获得 PDF 的 URL.

I am using AngularJS with ui-router. I am attempting to make use of the AngularJS PDF directive available at https://github.com/sayanee/angularjs-pdf. I'm having to make some changes to the example given because I do not have the URL to the PDF right off the bat.

但是,我遇到了一个问题.因为我将与 PDF 关联的 id 值传递到路由中,所以我必须等到路由更改成功才能解析该参数.我在 https://github.com/angular-ui/ui- 的指导下完成了这项工作路由器/维基在解决部分.

However, I ran into a problem. Because I pass an id value associated with the PDF into the route, I have to wait to resolve that parameter until the route change has been successful. I accomplished this with the guidance at https://github.com/angular-ui/ui-router/wiki under the Resolve section.

但是,当我访问该页面时,在任何这些问题得到解决之前,以及在我使用此 ID 向 API 进行查询以解析文件的 URL 之前,我发现自己点击了该指令.当然,我还没有用值填充指令的范围,因为路由还没有返回解析承诺,所以这是一个空值,最终在 pdf.js 中给我一个错误,即 url 不是't 已填充.

But, when, I visit the page, before any of this is resolved, and before I make the query to the API with this ID so as to resolve the URL of the file, I find myself clicking through the directive. Of course, I haven't populated the scope of the directive with the values since the route hasn't returned the resolve promise yet, so this is a null value, that ultimately give me an error in pdf.js that the url isn't populated.

如何延迟执行指令中的逻辑,直到根据需要适当填充作用域?

How can I delay executing the logic within the directive until the scope has been appropriately populated as I require?

所以你不必下载我在顶部链接的指令,这是我正在使用的:

So you don't have to download the directive I linked at the top, here's what I'm working with:

(function () {

    'use strict';

    angular.module('pdf', []).directive('ngPdf', function ($window) {
        return {
            restrict: 'E',
            templateUrl: function (element, attr) {
                return attr.templateUrl ? attr.templateUrl : 'viewer.html';
            },
            link: function (scope, element, attrs) {
                var url = scope.pdfUrl,
                  pdfDoc = null,
                  pageNum = 1,
                  scale = (attrs.scale ? attrs.scale : 1),
                  canvas = (attrs.canvasid ? document.getElementById(attrs.canvasid) : document.getElementById('pdf-canvas')),
                  ctx = canvas.getContext('2d'),
                  windowEl = angular.element($window);

                windowEl.on('scroll', function () {
                    scope.$apply(function () {
                        scope.scroll = windowEl[0].scrollY;
                    });
                });

                PDFJS.disableWorker = true;
                scope.pageNum = pageNum;

                scope.renderPage = function (num) {

                    pdfDoc.getPage(num).then(function (page) {
                        var viewport = page.getViewport(scale);
                        canvas.height = viewport.height;
                        canvas.width = viewport.width;

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

                        page.render(renderContext);

                    });

                };

                scope.goPrevious = function () {
                    if (scope.pageNum <= 1)
                        return;
                    scope.pageNum = parseInt(scope.pageNum, 10) - 1;
                };

                scope.goNext = function () {
                    if (scope.pageNum >= pdfDoc.numPages)
                        return;
                    scope.pageNum = parseInt(scope.pageNum, 10) + 1;
                };

                scope.zoomIn = function () {
                    scale = parseFloat(scale) + 0.2;
                    scope.renderPage(scope.pageNum);
                    return scale;
                };

                scope.zoomOut = function () {
                    scale = parseFloat(scale) - 0.2;
                    scope.renderPage(scope.pageNum);
                    return scale;
                };

                scope.changePage = function () {
                    scope.renderPage(scope.pageNum);
                };

                scope.rotate = function () {
                    if (canvas.getAttribute('class') === 'rotate0') {
                        canvas.setAttribute('class', 'rotate90');
                    } else if (canvas.getAttribute('class') === 'rotate90') {
                        canvas.setAttribute('class', 'rotate180');
                    } else if (canvas.getAttribute('class') === 'rotate180') {
                        canvas.setAttribute('class', 'rotate270');
                    } else {
                        canvas.setAttribute('class', 'rotate0');
                    }
                };

                PDFJS.getDocument(url).then(function (_pdfDoc) {
                    pdfDoc = _pdfDoc;
                    scope.renderPage(scope.pageNum);

                    scope.$apply(function () {
                        scope.pageCount = _pdfDoc.numPages;
                    });
                });

                scope.$watch('pageNum', function (newVal) {
                    if (pdfDoc !== null)
                        scope.renderPage(newVal);
                });

            }
        };
    });

})();

虽然我认为这不是特别必要,但这是我的控制器的简化视图:

Though I don't think it's particularly necessary, here's the simplified view of my controller:

angular.module('myApp').controller('myController', function($scope, $http, $state) {
 var url = "http://example.com/myService";
 $http.get(url)
  .success(function(data, status, headers, config) {
    $scope.pdfUrl = data.url;
    $scope.pdfName = data.name;
    $scope.scroll = 0;
    $scope.getNavStyle = function(scroll) {
      if (scroll > 100) return 'pdf-controls fixed';
      else return 'pdf-controls';
    }
  })
  .error(function(data, status, headers, config) {
    $state.go('failure.state');
  });
});

ui-view 如下所示:

The ui-view looks like the following:

<ng-pdf template-url="pathToTemplate/viewer.html" canvasid="pdf" scale="1.5"></ng-pdf>

谢谢!

推荐答案

看来您需要在加载控制器之前使用 ui-router 解析功能来获取 pdfUrl.例如,不要在控制器中使用 $http,您应该将 $http 调用的结果返回到路由解析函数,允许您将范围设置为控制器初始化.这是一个让您入门的基本示例(不会像编写的那样工作):

It looks like you need to use the ui-router resolve feature to get the pdfUrl before the controller is loaded. For example, instead of using $http inside your controller, you should be returning the result of the $http call to the routes resolve function, allowing you to set the scope on controller initialisation. This is a basic example (will not work as written) to get you started:

服务:

angular.module('myApp', [])
.factory('PdfService', ['$http', function($http){
        return {
            getURL: function(id){
                // return promise from http
                return $http(urlWithProvidedId).then(function(result){
                    // return all necessary result data as object to be injected
                    return {
                        url: result.data.url
                    };
                });    
            }
        };
    }]);    

然后在你的路由配置中:

Then inside your route config:

.state('somestate', { controller: 'myController', templateUrl: 'sometemplate.html',
    resolve: { _pdfData: ['PdfService', '$stateParams', function(PdfService, $stateParams) {                                
        return PdfService.getURL($stateParams.whateverThePdfIdIs);                              
    }]}});

然后将结果注入您的控制器

Then inject the result into your controller

.controller('myController', ['$scope', '_pdfData', function($scope, _pdfData){
    // set the pdf url
    $scope.pdfUrl = _pdfData.url;
}]);

另外,我想提一下,从角度方式的角度来看,您发布的指令设计得很差,这可能会导致您遇到困难.

Also, I want to mention that the directive you posted is quite poorly designed from an angular-way point of view, which likely plays into the difficulties you are having.

这篇关于如何延迟指令的运行逻辑,直到 ui-route 得到解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆