【问题标题】:Handling Promise and Observable on same variable in Node.js & Angular在 Node.js 和 Angular 中处理同一变量的 Promise 和 Observable
【发布时间】:2019-03-16 20:32:10
【问题描述】:

在我的项目中,我有一张图片。

初始化时;我从Promise<string> 加载它;其中 string 是 图像的 URL

然后我使用节点包来更改和裁剪图像。它要求图像,将其裁剪为请求的大小并返回Observable<anObject>,其中anObject.base64 是裁剪图像的base64 表示。它包含在一个对话框中。

我尝试了很多东西,但无法自动更改<img> 标签的图像。

这是我最后的设置:

image: Observable<string>;
...

ngOnInit() {

    ...

    prd.images.big.then(img => {
        this.image = of(img);
    });
    // prd.images.big is a Promise<string>

    ...
}


showImageDialog() {
    this.image = this.imageDialog.openDialog().pipe(
        map(data => {
            return data.base64;
        })
    );
}

还有我的模板: ....

<a style="cursor: pointer" (click)="showImageDialog();">
    <img [src]="(image | async) || 'an url to default image'"/>
</a>

....

奇怪的是,图像不会自动改变,但是当我再次点击图像时,它会改变。

我希望你们中的任何人都可以帮助实现这一目标。谢谢。

【问题讨论】:

    标签: node.js angular promise rxjs observable


    【解决方案1】:

    您当前正在为 this.image 分配订阅。相反,将 this.image 设置为 map 函数中返回的 data.base64。如果要对图像标签使用 base64 编码的图像字节,则需要使用 data URL

    如果您的图像类型是 jpeg: &lt;img src="data:image/jpeg;base64,{{image}}"/&gt;

    【讨论】:

    • 那么,您建议我将image 变量从Observable 更改为string?我说的对吗?
    • 顺便说一句,我在将代码从 IDE 复制到这里时犯了一个错误。再看看我的模板代码。
    • 是的,我建议这样做。此外,我建议使用我提供的 img 标签作为模板,而不是你所拥有的。如果需要,根据您拥有的图像格式替换图像/jpeg
    • 我有一个错误:Failed to load resource: unsupported URL unsafe:data:image/jpeg;base64,http://url.to.image... 天哪!我讨厌网络东西!
    • src 中不应包含实际的 URL,但 {{image}} 应包含您的库返回的 base64 编码的图像字节
    【解决方案2】:

    您希望避免在创建后重新分配 observable。试试这样的:

    image: Subject<string>;
    ...
    
    ngOnInit() {
    
        this.image = new ReplaySubject<string>(1);
    
        prd.images.big.then(img => this.image.next(img));
    }
    
    showImageDialog() {
        this.imageDialog.openDialog().subscribe(data => {
           const dataUrl = `data:image/jpeg;base64,${data.base64}`;
           this.image.next(dataUrl);
        });
    }
    

    仅供参考,Subject 只是一个充当观察者和可观察对象的变量——您可以像任何可观察对象一样订阅或管道操作,您也可以手动将值放入主题中,然后所有订阅者都将观察到。在上面的代码中,我使用了一种特殊的主题,它将向任何迟到的订阅者重播最新的值,以防万一你在视图有时间订阅之前输入了一个值。

    【讨论】:

    • 天啊!谢谢!使用Subject 解决了我的问题。但是,我真的不知道什么是主题;我从未使用过,也从未见过它的用法。
    • 糟糕。现在我有另一个问题。在我完成第一次图像选择和裁剪之后;当我尝试通过&lt;input type="file" (change)="fileChangeEvent($event)" /&gt; 选择另一个图像时,浏览器会冻结一段时间,大约 10 秒。在使用 Subject 之前没有发生。
    • 你在你的 filechangeeventhandler 中做什么?您应该只使用 FileReader readAsDataUrl 并获取结果字符串并调用 this.image.next(dataurl)
    • 我的 ngx-image-cropper 通过 $event 处理。
    • 好的。发现了问题。起初我没有在文件输入上添加文件 mime 检查器。并且不小心选择了一个大小为 gigs 的 dmg 文件。然后,当然,Safari 冻结了。我强行关闭它,然后重新启动角度服务器。即使这样,这个文件上传事件仍然存在,不知道如何,并且在短时间内冻结了浏览器。我重新启动了电脑。现在一切正常。我想应该是 macOS 或 Angular CLI 错误。谢谢你的一切!
    猜你喜欢
    • 2018-09-16
    • 2019-05-31
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 2020-04-19
    • 2019-11-19
    • 2016-08-07
    • 1970-01-01
    相关资源
    最近更新 更多