I have written an angular2 component to display embedded documents, but when I try to bind the mimetype of document it is not working.
html:
<div class="embed-responsive" *ngIf="mimeType!==null">
<object [attr.data]="url"
[attr.type]="mimeType"
class="embed-responsive-item">
<embed [attr.src]="url"
[attr.type]="mimeType"/>
</object>
</div>
working html without type binding:
<div class="embed-responsive" *ngIf="mimeType!==null">
<object [attr.data]="url"
type="application/pdf"
class="embed-responsive-item">
<embed [attr.src]="url"
type="application/pdf"/>
</object>
</div>
typescript code:
import { Component, Input, HostListener } from "@angular/core";
import { AttachmentFile } from "../../model/dockModel";
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
@Component({
selector: "document-viewer-inline",
templateUrl: "docview/components/document-viewer-inline-component/document-viewer-inline-component.html"
})
export class DocumentViewerInlineComponent {
private attachment: AttachmentFile;
public url: SafeUrl = null;
public mimeType: string = null;
constructor(private sanitizer: DomSanitizer) {
}
@Input()
public set attachmentFile(f: AttachmentFile) {
this.attachment = f;
if (this.attachment !== null && this.attachment !== undefined) {
this.url = this.sanitizer.bypassSecurityTrustResourceUrl("/attachment/contentById/" + this.attachment.componentId);
this.mimeType = f.mimeType;
}
}
public ngOnInit() {
this.calculateInlineHeight();
}
}
My question is: how can I bind the type attribute of embedded and object?
I haven't found where it's explicitly stated but I'm pretty sure <object>
doesn't support dynamic changes to the type
attribute and requires it to be set statically.
See also Changing data content on an Object Tag in HTML
Below workaround doesn't work - see comments:
A hack could be
<object *ngIf="mimeType!==null" [attr.data]="url"
[attr.type]="mimeType"
constructor(private cdRef:ChangeDetectorRef) {}
private _mimeType:string=null;
public get mimeType():string { return this._mimeType; }
public set mimeType(value:string) {
this._mimeType = null;
this.cdRef.detectChanges();
this._mimeType = value;
this.cdRef.detectChanges();
}
To make this more convenient to use you could wrap this with a custom <my-object>
component.
UPDATED hack:
public showObject: boolean = true;
public url: String = null;
// public url: SafeUrl = null;
constructor(@Inject(DomSanitizer) private sanitizer: DomSanitizer,
@Inject(ChangeDetectorRef) private cdRef: ChangeDetectorRef) {
}
@Input()
public set attachmentFile(f: FetAttachmentFile) {
this.attachment = f;
if (this.attachment !== null && this.attachment !== undefined) {
this.url = null;
this.mimeType = null;
this.showObject = false;
this.cdRef.detectChanges();
this.url = "/attachment/contentById/" + this.attachment.componentId;
// this.url = this.sanitizer.bypassSecurityTrustResourceUrl("/attachment/contentById/" + this.attachment.componentId);
this.mimeType = f.mimeType;
this.showObject = true;
this.cdRef.detectChanges();
}
}
public innerHtml() {
return this.sanitizer.bypassSecurityTrustHtml(
"<object data='" + this.url + "' type='" + this.mimeType + "' class='embed-responsive-item'>" +
"<embed src='" + this.url + "' type='" + this.mimeType + "' />" +
"</object>");
}
html code:
<div class="embed-responsive"
[style.height]="inlineHeight"
*ngIf="showObject"
[innerHTML]="innerHtml()">
</div>