【问题标题】:Make $http request, fill template with data and print it out发出 $http 请求,用数据填充模板并打印出来
【发布时间】:2016-03-11 21:30:18
【问题描述】:

我正在尝试从 jQuery 世界迁移到 Angular。
我尝试移植到 Angular 的功能之一是使用 AJAX 进行打印。想法是在客户端定义模板,向服务器发出请求,填写模板并打印。 我已经使用 Handlebars 完成了:

function drukuj(orderId, templateName) {
    var data;

    $.ajax({
        //zapis
        contentType: "application/json; charset=utf-8",
        type: "POST",
        url: "AJAX.asmx/Print",
        data: "{orderId: " + orderId + "}",

        success: function(msg) {
            data = JSON.parse(msg.d);

            var template = Handlebars.getTemplate(templateName).done(function(tpl) {
                var html = tpl(data);
                $.print(html);
            }).fail(function(err) {
                alert(err);
            });
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(textStatus);
        }
    });
};

现在我正在尝试将其转换为角度指令。这就是我所拥有的:

(function() {
    'use strict';

    angular
        .module('my.directives', [])
        .directive('printMe', ['$timeout', '$window', '$compile', '$rootScope', printMe]);


    function printMe($timeout, $window, $compile, $rootScope) {
        return {
            restrict: 'A',

            compile: function() {
                return function postLink(scope, element, attrs) {

                    var title = "Default title";

                    if (attrs.title) {
                        title = attrs.title;
                    }


                    element.on('click', function() {
                        print();
                    });

                    function print() {

                        var scope = $rootScope.$new();
                        angular.extend(scope, {
                            name: "Me",
                            items: [{
                                data: "One"
                            }, {
                                data: "Two"
                            }, {
                                data: "Three"
                            }]
                        });
                        var template = angular.element('<div ng-repeat="item in items">{{item.data}}</div>');
                        var linkFunction = $compile(template);
                        var result = linkFunction(scope);
                        scope.$apply();

                        console.log(result.html());


                        $timeout(function() {
                            var w = window.open('', '', 'width=595,height=842,scrollbars=1');
                            w.document.open();
                            w.document.write('<html><head>');
                            w.document.write('</head><body>');
                            w.document.write('<h1>' + title + '</h1>');
                            w.document.write(result.html());
                            w.document.write('</body></html>');
                            w.document.close();
                        });

                    }

                    // Cleanup on destroy
                    scope.$on('$destroy', function() {
                        element.off('click');
                    });
                };
            }
        };
    }
})();

想法是将模板作为变量(从 $templateCache 获取或硬编码),将数据作为变量(来自 $http 请求)并将它们编译成最终的 html,这样我就可以把它在新窗口中调用 print 就可以了。

我尝试了this questionthis 的解决方案,但我无法获取该html。

我创建了Plunker 来展示我现在创建的内容。

我还是 Angular 的新手,所以欢迎任何关于我的指令的 cmets。

【问题讨论】:

  • Angularjs 用于单页应用程序。您应该使用模式,而不是打开一个新窗口。看看这个:github.com/dwmkerr/angular-modal-service
  • @Walfrat 感谢您的评论,我会调查一下,但首先我必须解决打印问题。
  • 您可以使用此问题的答案来打印页面中当前显示的内容(无论是否处于模态):stackoverflow.com/questions/12181760/…
  • @Walfrat 我已经看到与github.com/samwiseduzer/angularPrint 类似的方法,但感谢您指出。我的问题是从模板中获取最终(编译的)HTML。这是我的主要问题。
  • 我认为你有所说的html,问题是你试图把它放在一个新窗口中。而且我不知道角度是否可以处理这个问题。 Angular 应该处理包装在 ng-app 中的内容,新窗口不在 ng-app 中。这就是我推荐模态方式的原因。

标签: javascript angularjs


【解决方案1】:

那是我的愚蠢,事实上,即使在新窗口中它也能很好地工作。

这是答案:将您当前的模板包装在一个 div 中,无需其他更改:

var template = angular.element('<div><div ng-repeat="item in items">{{item.data}}</div></div>');

这是因为 Angular 解析的指令可能不会创建 htmlnode 而是创建注释节点。所以你的 result.html() 不起作用。只需将所有模板包装在 DIV 标记中,无需任何指令绑定即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 2012-03-28
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多