【问题标题】:Creating a pdf from a Knockout JS view & viewModel从 Knockout JS 视图和视图模型创建 pdf
【发布时间】:2014-02-03 16:09:57
【问题描述】:

场景:在我们的应用程序中,用户可以通过填写 Knockout 视图中的某些字段来创建发票。可以通过另一个 Knockout 页面预览此发票。我想在我们的 PDF 创建器 (EVOPdf) 中使用预览 URL,因此我们可以为用户提供此发票的 PDF。

为了预览发票,我们通过 ajax 请求加载数据(准备好文档):

var InvoiceView = function(){
    function _start() {
        $.get("invoice/GetInitialData", function (response) {
            var viewModel = new ViewModel(response.Data);
            ko.applyBindings(viewModel, $("#contentData").get(0));
        });
    };
    return{
        Start: _start
    };
}();

当 PDF 创建者请求 url 时,我的问题在于数据绑定:viewModel 为空。这是有道理的,因为当 PDF 创建者执行请求时,不会调用 GetInitialData 操作。在页面末尾直接从预览页面调用此_start 函数也无济于事。

<script type="text/javascript">
    $(document).ready(function() {
        InvoiceView.Start();
    });
</script>

查看EvoPdf的文档,应该执行JavaScript,因为JavaScriptEnabled默认为truehttp://www.evopdf.com/api/index.aspx

我该如何解决这个问题,或者从淘汰视图创建 pdf 的最佳方法是什么?

控制器动作代码:

public FileResult PdfDownload(string url)
{
    var pdfConverter = new PdfConverter();

    // add the Forms Authentication cookie to request
    if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
    {
        pdfConverter.HttpRequestCookies.Add(
            FormsAuthentication.FormsCookieName,
            Request.Cookies[FormsAuthentication.FormsCookieName].Value);
    }

    var pdfBytes = pdfConverter.GetPdfBytesFromUrl(url);

    return new FileContentResult(pdfBytes, "application/pdf");
}

Javascript:

var model = this;
model.invoiceToEdit = ko.observable(null);

model.downloadInvoice = function (invoice) {
    model.invoiceToEdit(invoice);
    var url = '/invoice/preview';
    window.location.href = '/invoice/pdfDownload?url=' + url;
};

【问题讨论】:

  • 可能是ajax请求延迟造成的。对于 PDF 创建者,javascript 已经执行并且文档已准备就绪,但实际上,您正在等待 ajax 完成并填充视图模型。您可以尝试在初始页面请求中提供 ajax,以消除在页面加载后立即执行 ajax 调用的需要。

标签: asp.net-mvc-4 knockout.js evopdf


【解决方案1】:

xdumaine 的评论让我想到了另一个方向,谢谢!

加载 Ajax 请求确实需要一些时间,但在我将 ConversionDelay 放在 pdf 创建者对象上之后,我还发现了一些 JavaScript(例如敲除绑定)错误

pdfConverter.ConversionDelay = 5; //time in seconds

所以这是我目前的解决方案,现在对我有用:

要启动绑定点击事件的流程:

model.downloadInvoice = function (invoice) {
    var url = '/invoice/preview/' + invoice.Id() + '?isDownload=true';
    window.open('/invoice/pdfDownload?url=' + url);
};

这会导致对控制器操作的 GET 请求

public FileResult PdfDownload(string url)
{
    var pdfConverter = new PdfConverter { JavaScriptEnabled = true };

    // add the Forms Authentication cookie to request
    if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
    {
        pdfConverter.HttpRequestCookies.Add(
            FormsAuthentication.FormsCookieName,
            Request.Cookies[FormsAuthentication.FormsCookieName].Value);
    }

        pdfConverter.ConversionDelay = 5; 
        var absolutUrl = ToAbsulte(url);
        var pdfBytes = pdfConverter.GetPdfBytesFromUrl(absolutUrl);

        return new FileContentResult(pdfBytes, "application/pdf");
}

Pdf 创建者通过isDownload = true 请求在控制器上执行此操作(请参阅绑定的点击事件):

public ActionResult Preview(string id, bool isDownload = false)
{
    return PartialView("PdfInvoice", new InvoiceViewModel
    {
        IsDownload = isDownload,
        InvoiceId = id
    });
}

返回这个局部视图:

部分视图:

// the actual div with bindings etc.
@if (Model.IsDownload)
{
    //Include your javascript and css here if needed
    @Html.Hidden("invoiceId", Model.InvoiceId);

    <script>
        $(document).ready(function () {
            var invoiceId = $("#invoiceId").val();
            DownloadInvoiceView.Start(invoiceId);
        });
    </script>
}

用于获取发票和应用敲除绑定的 JavaScript:

DownloadInvoiceView = function() {
   function _start(invoiceId) {
        $.get("invoice/GetInvoice/" + invoiceId, function(response) {
            var viewModel = new DownloadInvoiceView.ViewModel(response.Data);
            ko.applyBindings(viewModel, $("#invoiceDiv").get(0));
        });
    };

    return {
        Start: _start
    };

}();

DownloadInvoiceView.ViewModel = function (data) {
    var model = this;
    var invoice = new Invoice(data); //Invoice is a Knockout model

    return model;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 2013-01-03
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多