【问题标题】:Angular CLI phonegap pluginsAngular CLI phonegap 插件
【发布时间】:2018-02-26 12:52:27
【问题描述】:

我是 phonegap 的新手,也是 angular cli 的新手,所以请假设我一无所知,并提供完整的示例和您的答案。您如何在 Angular 5 项目中使用 phonegap 插件?

我制作了一个使用 .net 核心 web api 后端的 Angular 网站,它可以在 phonegap 中运行 - 但是我需要使用插件,特别是我相信的 FileWriter。我的应用程序需要做的一件事是生成 PDF 服务器端并将其作为文件传递回客户端 - 这需要保存到手机/在手机上打开。我的 webapi 方法返回一个 FileContentResult。在该页面的角度 ts 文件中,我使用了一个名为 filesaver 的 npm 库,并且在成功请求获取所述 pdf 文件时,我会将返回的结果粘贴到 blob 中并使用 filesaver saveAs 方法弹出文件保存对话框。 .. 这在桌面网络浏览器上效果很好,但是当我在我的 android 手机上的 phonegap dev 应用程序中运行它时它不起作用。

所以经过一番挖掘后,我认为我需要使用在运行时注入的 phonegap 插件之一。

我的问题是我不知道该怎么做。到目前为止,我在 Angular 应用程序中使用的所有插件都是使用 npm 下载的,然后我可以在 ts 文件中引用一个物理库...例如:

import { DataService } from '../shared/dataService'
import { Component, OnInit } from "@angular/core";
import { saveAs } from 'file-saver/FileSaver'
...

然后当我调用我的 web api 方法时,我可以像这样引用 saveAs:

this.data.generatePdf(myParam).subscribe(data => {
let fileName = "portfolioValuation.pdf";
var blob = new Blob([data], { type: 'application/pdf' });
saveAs(blob, fileName);
}

我假设导入知道这些方法和库,因为它们位于 node_modules 文件夹中 - 我不记得了,但我假设我在某个时候告诉 angular 关于 node_module 文件夹 - 或者它只是内置在 angular 中,因为你是用 npm 安装的吗??

无论如何,phonegap 插件似乎是在运行时生成的,因此我在 node_modules 文件夹中没有它们。相反,它们位于我的 phonegap 项目文件夹的 plugins 文件夹中,因此我无法引用它们 - 然后 angular 不知道它们 - 所以它用红色强调它,我认为它不会构建。

那么我该如何在我的 ts 文件中使用这些 phonegap 插件呢?特别是文件编写器 - 也因为我在谈论文件编写器,这是我需要的插件,以便将返回的文件保存到手机上?我想要的只是允许移动用户单击一个按钮并能够打开返回的 pdf。

非常感谢您的帮助

【问题讨论】:

    标签: angular cordova angular-cli phonegap


    【解决方案1】:

    我无法使用这种确切的方法来工作,所以我已经解决了这个问题。我可能已经接近我最初的尝试,所以我会分享它以防它有帮助 - 但我也会分享我的工作。

    所以我的 .net 核心 web api 方法返回一个文件内容结果,如下所示:

    return File(pdfBuffer, "application/pdf", fileName);
    

    pdfBuffer 是一个字节[],后跟 MIME 类型和文件名。

    在我的 Angular 数据服务 ts 文件中,我这样调用这个方法:

    public generatePdf(param1) {
        let body = {
            "param1": param1
        };
    
        let pdfOptions = new RequestOptions();
        pdfOptions.headers = this.options.headers;
        pdfOptions.responseType = ResponseContentType.Blob;
    
        return this.http.post("https://myWebsite/api/GeneratePdf", body, pdfOptions)
            .map((res: Response) => res.blob());
    }
    

    我已重命名变量和方法名称等,但您可以看到我已将响应类型指定为 blob 并将响应映射为这样。我还从我正在使用的包含身份验证令牌的通用标头中复制了标头

    在页面 ts 文件中调用它后,我订阅了,这就是我开始遇到问题的地方......

    为了让 cordova 能够在我的 ts 文件中使用,我在项目根目录下的 tsconfig.json 文件中添加了以下内容:

    "types": [
      "cordova",
      "cordova-plugin-file"
    ],
    

    我还使用 npm 将 phonegap 和 cordova 库安装到我的项目中。

    在页面的 ts 文件中,我在导入下添加了以下变量,以便我可以获取注入的 cordova 库:

    declare var window: any;
    declare var LocalFileSystem: any;
    declare var device: any;
    var storageLocation = "";
    declare var cordova: any;
    

    然后这个方法将blob保存或显示为pdf:

    public generatePdf() {
        let param1= param1Logic;
        $("#waitingAnimation").show();
    
        this.data.generatePdf(param1).subscribe(data => {
            let fileName = "myDocument.pdf";
            var blob = new Blob([data], { type: 'application/pdf' });
            $("#waitingAnimation").hide();
    
            //I tried to just open the pdf on the device like so... just get a blank white page on phonegap
            //var fileURL = URL.createObjectURL(blob);
            //window.open(fileURL); // if you want to open it in new tab 
    
    
            switch (device.platform) {
    
                case "Android":
                    storageLocation = 'file:///storage/emulated/0/';
                    break;
                case "iOS":
                    storageLocation = cordova.file.documentsDirectory;
                    break;
    
            }
    
            window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
    
                console.log('file system open: ' + fs.name);
                let parentEntry = storageLocation + "Download/" + fileName;
                fs.root.getFile(parentEntry, { create: true, exclusive: false }, function (fileEntry) {
                    fileEntry.createWriter(function (fileWriter) {
                        console.log('create writer');
    
                        fileWriter.onerror = function (e) {
                            console.log("Failed file write: " + e.toString());
                        };
    
                        fileWriter.write(blob);
                    });
    
                }, null);
    
            }, null);
    
        });
    }
    

    这可能不是确切的代码——我做了很多修改而没有保存到存储库——所以我只是从我留在代码中的 cmets 粗略地把它放在一起。我没有收到任何控制台错误 - 它什么也没做。

    我认为这与作为 blob 的响应有关,与白名单有关。我开始阅读它,发现它有安全隐患,我找不到任何描述如何使它安全的东西,所以此时我开始考虑其他解决方案。

    所以我的工作...

    我想我会尝试从另一个旧的 aspx 网站获取 pdf,该网站只需要对该 ashx 页面的简单获取请求,该页面只返回一个 pdf MIME 类型的 pdf 文件。我可以用 Angular 调用它,并使用以下代码在浏览器中打开 pdf:

    window.open("https://myWebsite.ashx?fileName=" + fileName, '_system', 'location=no');
    

    所以我所做的就是更改我的 Web API 来解决这个问题。

    不是使用 post 来响应 blob,而是该 post 到服务器创建一个 pdf,该文件存储在服务器上的临时目录中 - 此 post 方法使用一些带有文件名的 JSON 响应。

    然后我创建了另一个 Web API 方法,该方法接受一个以文件名作为参数(查询字符串)的 get 请求,这会查找该临时文件(我知道服务器位置,并且只需附加提供的文件名) - 如果文件存在我像以前一样用 FileContentResult 响应并从临时存储中删除文件。像这样:

        [HttpGet]
        [DeleteFileAttribute]
        public IActionResult Get(string fileName)
        {
            var tempPath = $"serverLocationGoesHere/{fileName}";
            byte[] fileBytes = System.IO.File.ReadAllBytes(tempPath);
            return File(fileBytes, "application/pdf", fileName);
        }
    

    DeleteFileAttribute 是我为删除文件而创建的自定义属性。

    所以现在在我的 dataService ts 文件中,我调用初始 GeneratePdf post 方法来生成 pdf:

    public generatePdf(param1) {
        let body = {
            "param1": param1
        };
    
        return this.http.post("https://myWebSite/api/GeneratePdf", body, this.options)
            .map((res: Response) => {
                return res.json();
            });
    }
    

    如您所见,这只是返回 JSON...

    所以在我的页面 ts 文件中,我需要做的就是:

    public generatePdf() {
        let param1 = param1Logic;
        $("#waitingAnimation").show();
    
        this.data.generatePdf(param1).subscribe(data => {
            let fileName = data.fileName;
            $("#waitingAnimation").hide();
            window.open("https://myWebsSite/api/DownloadFile?fileName=" + fileName, '_system', 'location=no');
    
    }
    

    现在我可以在我的 phonegap 应用程序中打开服务器生成的 PDF - 尽管不是按照我想要的方式。我确信有更好的方法也可以使用一些库打开 Pdf - 但希望这里有一些对某人有用的东西!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-29
      • 1970-01-01
      • 1970-01-01
      • 2016-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多