【问题标题】:Angular Can't change ng-model form other directiveAngular 无法更改 ng-model 形式的其他指令
【发布时间】:2016-03-28 08:48:12
【问题描述】:

我需要通过单击 pdfViewer 指令中的画布来更改 pdfViewerToolbar 指令中的 ng-model (currentPage)。当我点击画布时,控制器中的 self.next 函数被调用,但 ng-model="currentPage" 在 pdfViewerToolbar 指令中没有改变。

app.angular.module("pdf").directive("pdfViewerToolbar", ["pdfDelegate", function(e) {
    return {
        restrict: "E",
        template: '<div  class="pdf_navigation" ng-show="navBar">\
            <div class="pdf_buttons">\
                <div ng-click="prev()" class="goPrevious" title="previous page"></div>\
                <div ng-click="next()" class="goNext" id="goNext" title="next page"></div>\
                <div ng-click="zoomOut()" class="zoomIn"></div>\
                <div ng-click="zoomIn()" class="zoomOut"></div>\
            </div>\
            <div class="pdf_page">\
                <span>Page</span>\
                <input type="text" min=1 ng-model="currentPage" maxlength="4" ng-change="goToPage()" >\
                <span>of {{pageCount}}</span>\
            </div>\
        </div>',
        scope: {
            pageCount: "=",
            navBar: "=",
        },
       // controller: "PdfCtrl",
        link: function(t, n, a) {
            var o = a.delegateHandle;
            t.currentPage = 1, t.prev = function() {
                e.$getByHandle(o).prev(), r()
            }, t.next = function() {
                e.$getByHandle(o).next(), r()
            }, t.zoomIn = function() {
                e.$getByHandle(o).zoomIn()
            }, t.zoomOut = function() {
                e.$getByHandle(o).zoomOut()
            }, t.rotate = function() {
                e.$getByHandle(o).rotate()
            }, t.goToPage = function() {
                e.$getByHandle(o).goToPage(t.currentPage)
            };
            var r = function() {
                t.currentPage = e.$getByHandle(o).getCurrentPage()
            }


        }
    }
}])

app.angular.module("pdf").directive("pdfViewer", ["pdfDelegate", function(r) {
    return {
        restrict: "E",
        template: '<div show-control class="pdf_doc"><pdf-viewer-toolbar ng-if="showToolbar" delegate-handle="{{id}}" page-count="pageCount" nav-bar="pdfNavigationBar"></pdf-viewer-toolbar><canvas ng-click="next()" id="pdf-canvas" ></canvas></div>',
        scope: false,
        controller: "PdfCtrl",
        link: function(e, t, n) {
            e.id = n.delegateHandle, e.showToolbar = e.$eval(n.showToolbar) || !1

           var o = n.delegateHandle;
            e.currentPage = 1,
            e.next = function() {
                r.$getByHandle(o).next(), s()
            }

            var s = function() {
                e.currentPage = r.$getByHandle(o).getCurrentPage()
            }


        }


    }
}]);


app.controller('PdfCtrl', [
    '$scope',
    '$element',
    '$attrs',
    'pdfDelegate',
    '$log',
    '$q', '$rootScope',
    function($scope, $element, $attrs, pdfDelegate, $log, $q, $rootScope) {

        // Register the instance!
        var deregisterInstance = pdfDelegate._registerInstance(this, $attrs.delegateHandle);
        // De-Register on destory!
        $scope.$on('$destroy', deregisterInstance);

        var self = this;

        var url = $scope.$eval($attrs.url);
        var headers = $scope.$eval($attrs.headers);
        var pdfDoc;
        $scope.pageCount = 0;
        var currentPage = 1;
        var angle = 0;
        var scale = $attrs.scale ? $attrs.scale : 1;
        var canvas = $element.find('canvas')[0];
         var ctx = canvas.getContext('2d');

        self.next = function() {
            if (currentPage >= pdfDoc.numPages)
                return;
            currentPage = parseInt(currentPage, 10) + 1;

            renderPage(currentPage);

            console.log('currentPage'+currentPage);
        };

            return PDFJS
                .getDocument(docInitParams)
                .then(function (_pdfDoc) {
                    console.log('loaded');
                    $rootScope.loadPdf = $scope.pdfNavigationBar = true;

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

                }, function(error) {
                    $log.error(error);
                    return $q.reject(error);
                })
        };

        if(url) self.load();
    }]);

【问题讨论】:

    标签: angularjs directive angular-directive


    【解决方案1】:

    您需要将 currentPage 变量作为隔离指令传递,如下所示。

     return {
        restrict: "E",
        template: '<div  class="pdf_navigation" ng-show="navBar">\
            <div class="pdf_buttons">\
                <div ng-click="prev()" class="goPrevious" title="previous page"></div>\
                <div ng-click="next()" class="goNext" id="goNext" title="next page"></div>\
                <div ng-click="zoomOut()" class="zoomIn"></div>\
                <div ng-click="zoomIn()" class="zoomOut"></div>\
            </div>\
            <div class="pdf_page">\
                <span>Page</span>\
                <input type="text" min=1 ng-model="currentPage" maxlength="4" ng-change="goToPage()" >\
                <span>of {{pageCount}}</span>\
            </div>\
        </div>',
        scope: {
            pageCount: "=",
            navBar: "=",
            currentPage: "="
        },
        ...
        ...
        ...
    

    现在从 pdfViewer 指令模板传递当前页面,如下所示:

    app.angular.module("pdf").directive("pdfViewer", ["pdfDelegate", function(r) {
        return {
        restrict: "E",
        template: '<div show-control class="pdf_doc"><pdf-viewer-toolbar ng-if="showToolbar" delegate-handle="{{id}}" page-count="pageCount" nav-bar="pdfNavigationBar" current-page="currentPage" ></pdf-viewer-toolbar><canvas ng-click="next()" id="pdf-canvas" ></canvas></div>',
        scope: false,
        controller: "PdfCtrl",
    

    现在在控制器 PdfCtrl 的范围内定义变量并从其访问。

    app.controller('PdfCtrl', [
    '$scope',
    '$element',
    '$attrs',
    'pdfDelegate',
    '$log',
    '$q', '$rootScope',
    function($scope, $element, $attrs, pdfDelegate, $log, $q, $rootScope) {
    
        // Register the instance!
        var deregisterInstance = pdfDelegate._registerInstance(this, $attrs.delegateHandle);
        // De-Register on destory!
        $scope.$on('$destroy', deregisterInstance);
    
        var self = this;
    
        var url = $scope.$eval($attrs.url);
        var headers = $scope.$eval($attrs.headers);
        var pdfDoc;
        $scope.pageCount = 0;
        $scope.currentPage = 1;
        var angle = 0;
        var scale = $attrs.scale ? $attrs.scale : 1;
        var canvas = $element.find('canvas')[0];
         var ctx = canvas.getContext('2d');
    
        self.next = function() {
            if ($scope.currentPage >= pdfDoc.numPages)
                return;
            $scope.currentPage = parseInt($scope.currentPage, 10) + 1;
    
            renderPage($scope.currentPage);
    
            console.log('currentPage'+$scope.currentPage);
        };
    

    【讨论】:

      【解决方案2】:

      在您的 pdfViewerToolbar 指令中,scope 是孤立的,如果您想更改该指令中的某些内容,您可以将其作为具有两种数据绑定方式的范围元素传递:"="

      scope: {
              pageCount: "=",
              navBar: "=",
              currentPage:"="
          }
      

      并像这样使用您的指令传递控制器模型

      <pdf-viewer-toolbar page-count="ctrlModelPageCount" nav-bar="ctrlModelNavBar" current-page="ctrlModelCurrentPage"></pdf-viewer-toolbar>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-09
        • 2021-03-19
        • 1970-01-01
        相关资源
        最近更新 更多