Angular一次性绑定图片属性源
Angular Binding a Image Attribute Source just for One-Time
只有一次,从 Observable 中 ngOnInit
触发,我收到一个 JSON 带有文本和图像的对象。
图片以数组的形式出现。 Text-Binding 效果很好,但图像的源属性绑定是一个杀手 - 图像的数据可以达到 1MB 甚至更多。
Text <h2>{{support.VehicleName}}</h2>
可以从另一个 Observable 改变,这部分效果很好。但我不需要更改图像。如何一次性绑定我的图像源?
HTML:
<div *ngFor="let support of IsSupportInOperation">
<h2>{{support.VehicleName}}</h2>
<img [src]='innerHtml(support.VehicleImage.data)' />
</div>`
打字稿:
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'
import { FireCrewService, ViewOnSupportInOperation } from '../shared/fire-crew.service';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
selector: 'app-display',
templateUrl: './display.component.html',
styleUrls: ['./display.component.css']
})
export class DisplayComponent implements OnInit {
@Input() OperationId: number = 0;
destroy$ = new Subject();
IsSupportInOperation = new Array<ViewOnSupportInOperation>();
observer = {
next: (value: ViewOnSupportInOperation[]) => this.onNext(value),
error: (err: string) => this.onError(err),
complete: () => this.onComplete(),
};
constructor(private fs: FireCrewService,
private sanitizer: DomSanitizer) {
}
ngOnDestroy(): void {
this.destroy$.next();
}
ngOnInit(): void {
this.fs.getAlarm(this.OperationId)
.pipe(takeUntil(this.destroy$))
.subscribe(this.observer);
}
onNext(value: ViewOnSupportInOperation[]): void
{
this.IsSupportInOperation = [];
value.forEach(element => {
if (element.SrcId == element.DstId) {
this.IsSupportInOperation.push(element);
}
});
}
onError(value: string): void {
}
onComplete(): void {
}
innerHtml(value: Buffer) {
return this.sanitizer.bypassSecurityTrustUrl('data:image/jpeg;base64,' + this._arrayBufferToBase64(value));
}
_arrayBufferToBase64(value: Buffer) {
var binary = '';
var bytes = new Uint8Array(value);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
}
SQL:
CREATE TABLE [dbo].[Vehicle]
(
[Id] INT IDENTITY (1, 1) NOT NULL
, [SrcId] INTEGER NOT NULL
, [DstId] INTEGER NOT NULL
, [VehicleName] NVARCHAR (32) NOT NULL
, [VehicleImage] VARBINARY(MAX) NULL
)
接口:
export interface ViewOnSupportInOperation {
Id: number;
SrcId: number;
DstId: number;
VehicleName: string;
VehicleImage: any;
}
JSON:
[
{
"Id":1,
"VehicleName":"Car",
"VehicleImage": {
"type":"Buffer",
"data":[
255,254,253, ...
]
}
}
]
API:
async function getAlarm(id) {
try {
let pool = await sql.connect(config);
let query = await pool.request().query("SELECT * FROM Vehicle WHERE Id = " + id);
return query.recordset;
}
catch (error) {
console.error(error);
}
}
我找到了解决方案,我用 MySafeUrl: SafeUrl
扩展了我的 ViewOnSupportInOperation
界面:
export interface ViewOnSupportInOperation {
Id: number;
SrcId: number;
DstId: number;
VehicleName: string;
VehicleImage: any;
MySafeUrl: SafeUrl;
}
在我的 onNext
中,我计算了 SafeUrl element.MySafeUrl = this.innerHtml(element.VehicleImage.data);
:
onNext(value: ViewOnSupportInOperation[]): void
{
this.IsSupportInOperation = [];
value.forEach(element => {
element.MySafeUrl = this.innerHtml(element.VehicleImage.data);
if (element.SrcId == element.DstId) {
this.IsSupportInOperation.push(element);
}
});
}
HTML,更改为<img [src]=support.MySafeUrl />
:
<div *ngFor="let support of IsSupportInOperation">
<h2>{{support.VehicleName}}</h2>
<img [src]=support.MySafeUrl />
</div>`
只有一次,从 Observable 中 ngOnInit
触发,我收到一个 JSON 带有文本和图像的对象。
图片以数组的形式出现。 Text-Binding 效果很好,但图像的源属性绑定是一个杀手 - 图像的数据可以达到 1MB 甚至更多。
Text <h2>{{support.VehicleName}}</h2>
可以从另一个 Observable 改变,这部分效果很好。但我不需要更改图像。如何一次性绑定我的图像源?
HTML:
<div *ngFor="let support of IsSupportInOperation">
<h2>{{support.VehicleName}}</h2>
<img [src]='innerHtml(support.VehicleImage.data)' />
</div>`
打字稿:
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'
import { FireCrewService, ViewOnSupportInOperation } from '../shared/fire-crew.service';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
selector: 'app-display',
templateUrl: './display.component.html',
styleUrls: ['./display.component.css']
})
export class DisplayComponent implements OnInit {
@Input() OperationId: number = 0;
destroy$ = new Subject();
IsSupportInOperation = new Array<ViewOnSupportInOperation>();
observer = {
next: (value: ViewOnSupportInOperation[]) => this.onNext(value),
error: (err: string) => this.onError(err),
complete: () => this.onComplete(),
};
constructor(private fs: FireCrewService,
private sanitizer: DomSanitizer) {
}
ngOnDestroy(): void {
this.destroy$.next();
}
ngOnInit(): void {
this.fs.getAlarm(this.OperationId)
.pipe(takeUntil(this.destroy$))
.subscribe(this.observer);
}
onNext(value: ViewOnSupportInOperation[]): void
{
this.IsSupportInOperation = [];
value.forEach(element => {
if (element.SrcId == element.DstId) {
this.IsSupportInOperation.push(element);
}
});
}
onError(value: string): void {
}
onComplete(): void {
}
innerHtml(value: Buffer) {
return this.sanitizer.bypassSecurityTrustUrl('data:image/jpeg;base64,' + this._arrayBufferToBase64(value));
}
_arrayBufferToBase64(value: Buffer) {
var binary = '';
var bytes = new Uint8Array(value);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
}
SQL:
CREATE TABLE [dbo].[Vehicle]
(
[Id] INT IDENTITY (1, 1) NOT NULL
, [SrcId] INTEGER NOT NULL
, [DstId] INTEGER NOT NULL
, [VehicleName] NVARCHAR (32) NOT NULL
, [VehicleImage] VARBINARY(MAX) NULL
)
接口:
export interface ViewOnSupportInOperation {
Id: number;
SrcId: number;
DstId: number;
VehicleName: string;
VehicleImage: any;
}
JSON:
[
{
"Id":1,
"VehicleName":"Car",
"VehicleImage": {
"type":"Buffer",
"data":[
255,254,253, ...
]
}
}
]
API:
async function getAlarm(id) {
try {
let pool = await sql.connect(config);
let query = await pool.request().query("SELECT * FROM Vehicle WHERE Id = " + id);
return query.recordset;
}
catch (error) {
console.error(error);
}
}
我找到了解决方案,我用 MySafeUrl: SafeUrl
扩展了我的 ViewOnSupportInOperation
界面:
export interface ViewOnSupportInOperation {
Id: number;
SrcId: number;
DstId: number;
VehicleName: string;
VehicleImage: any;
MySafeUrl: SafeUrl;
}
在我的 onNext
中,我计算了 SafeUrl element.MySafeUrl = this.innerHtml(element.VehicleImage.data);
:
onNext(value: ViewOnSupportInOperation[]): void
{
this.IsSupportInOperation = [];
value.forEach(element => {
element.MySafeUrl = this.innerHtml(element.VehicleImage.data);
if (element.SrcId == element.DstId) {
this.IsSupportInOperation.push(element);
}
});
}
HTML,更改为<img [src]=support.MySafeUrl />
:
<div *ngFor="let support of IsSupportInOperation">
<h2>{{support.VehicleName}}</h2>
<img [src]=support.MySafeUrl />
</div>`