Dynamically load AMP html with AngularElements
AngularDay 23
WARNING: This is a Google translated (originally Chinese) and reposted article that probably is mostly comfortably understandable for senior Angular developers.
angular
In this article we try to load AMP html using AngularElements.
About Angular Elements
It is possible to add AngularComponent directly to DOM without going through the tree below the bootstrap .
How to use Elements in Angular app
A sample of the official document is currently in this use case. How to realize dynamic components within Angular application. In the sample, there are two ways of doing it as it is with AngularComponent and one using customElement.
How to build and distribute it as one-shot customElements and use it from other applications
This article is very high quality.
I will understand the bootstrap of customElement and the external interface with other elements. In conclusion it is ivy wait.
Also, although it is an official document , it seems likely that it will be out of time as the issue of putting use case for distribution is up.
Load AMP html with AngularElements
- Use AngularElements.
- Read AMP html from the server and set it in iframe of elements.
Implementation
We will proceed based on samples of the official document.
Prepare a component for AMP display
I will make a component as usual. srcdocI am trying to set an AMPhtml source acquired with XHR by preparing an iframe tag . This component later cusutomElement. Then @Inputit becomes the property attribute of HTMLElement.
amp-display.component.ts
@Component({
selector: 'app-amp-display',
template: `
`
})
export class AmpDisplayComponent {
safeMsg: SafeHtml;
/ / It becomes a property attribute when it converts to customElement.
@ Input ()
The set message ( message : string ) {
this . SafeMsg = this . Sanitizer . BypassSecurityTrustHtml ( message );
}
@ Output ()
closed = new EventEmitter ();
constructor ( private sanitizer : DomSanitizer ) {}
}
to customElement
Here is a sample of the official document. Source comments are completely Copy by all means.
In the constructor of AppComponent window.customElements, register the component with NgElement before converting it . This is now a standard custom element. It can be operated from the DOM API . On the contrary, trying to handle it within Angular, for example , even if you set template, various difficulties will come.
app.component.ts
@Component({
selector: 'app-root',
template: `
`
})
export class AppComponent {
constructor(injector: Injector, public ampDisplay: AmpDisplayService) {
// Convert `PopupComponent` to a custom element.
const AmpDisplayElement = createCustomElement(AmpDisplayComponent, {
injector
});
// Register the custom element with the browser.
customElements.define('amp-display-element', AmpDisplayElement);
}
}
Load AMP
Wake up the service and responseType: 'text'load the AMP source from the server with. The AMP source is a full html document below the tag that can be displayed normally if you hit the URL .
@Injectable()
export class AmpDisplayService {
private ampUrl = 'http://localhost:8080/amp';
constructor(
private http: HttpClient
) {}
private getContent() {
return this.http.get(this.ampUrl, { responseType: 'text' });
}
}
Call customElement from within Angular application
Add a method to grant customElement to service to service. Since it is already registered in window, document.createElement()you can create with. @Input() messageSince it has been converted as a property attribute of HTMLElement, we pass the acquired AMP source.
@Injectable()
export class AmpDisplayService {
private ampUrl = 'http://localhost:8080/amp';
constructor(
private injector: Injector,
private http: HttpClient
) {}
// This uses the new custom-element method to add the popup to the DOM.
showAsElement() {
// Create element
const ampDisplayEl: NgElement &
WithProperties<AmpDisplayComponent> = document.createElement(
'amp-display-element'
) as any;
// Listen to the close event
ampDisplayEl.addEventListener('closed', () =>
document.body.removeChild(ampDisplayEl)
);
this.getContent().subscribe(text => {
// Set the message
ampDisplayEl.message = text;
// Add to the DOM
document.body.appendChild(ampDisplayEl);
});
}
}
Prepare APM content
We prepared an HTML document with reference to the following AMP tutorial. express from the server.
result
When I press the button, I get the AMP source from the server and show it in toast. The gray background is the AMP source.
Repository
The code of this time is up to here.
What I really wanted to do
Honestly, the iframe ran away. What I really wanted to do is to tell you that AMP is displayed using shadowDOM instead of iframe 2 . It will be meaningful to use AngularElements as customElement when it comes. However, it was not a shadowRoot to add the tags below as they were, but it was window.AMP.attachShadowDoc()timed due to elucidation of the mysterious module that is prepared by the AMP project . There is a sample implementation of react, so if you are interested please try it.
I think that you can see what you are doing roughly by looking at demo site 3 . In fact, it window.AMP.attachShadowDoc()was possible to use Angular even if it is a method which applies to the whole document instead of controlling the output destination to the specific area which was about to be done this time. I might look at the opportunity and write an article again.
- https://choumx.github.io/amp-pwa from AMPhtml and with only the removal tag is a feeling that is applied to the shadowRoot. Or looks like movement applied to host's react document. shadow-v0.jsIt is speculation from the output result because I think that it is not made into OSS. A