{"id":2366,"date":"2019-04-03T14:53:56","date_gmt":"2019-04-03T12:53:56","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=2366"},"modified":"2019-04-03T14:53:56","modified_gmt":"2019-04-03T12:53:56","slug":"angular-elements-part-iii","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/","title":{"rendered":"Angular Elements, Part III"},"content":{"rendered":"<div class=\"article\">\n<hr>\n<div style=\"font-size:14px\">\n<b style=\"font-weight: bold\">This blog post is part of an article series.<\/b><\/p>\n<ul class=\"toc\">\n<li><a href=\"https:\/\/www.angulararchitects.io\/post\/2018\/07\/13\/angular-elements-part-i-a-dynamic-dashboard-in-four-steps-with-web-components.aspx\">Angular Elements, Part I: A Dynamic Dashboard In Four Steps With Web Components<\/a><\/li>\n<li><a href=\"https:\/\/www.angulararchitects.io\/post\/2018\/07\/29\/angular-elements-part-ii-lazy-and-external-web-components.aspx\">Angular Elements, Part II: Lazy And External Web Components<\/a><\/li>\n<li><a href=\"https:\/\/www.angulararchitects.io\/post\/2018\/07\/06\/angular-elements-without-zone-js.aspx\">Angular Elements, Part III: Angular Elements without Zone.js<\/a><\/li>\n<li><a href=\"https:\/\/www.angulararchitects.io\/post\/2018\/10\/31\/content-projection-with-slots-in-angular-elements-7.aspx\" target=\"_blank\" rel=\"noopener\">Angular Elements, Part IV:&nbsp;Content Projection with Slots in Angular Elements (&gt;=7)<\/a><\/li>\n<li><a href=\"https:\/\/www.angulararchitects.io\/post\/2019\/01\/27\/building-angular-elements-with-the-cli.aspx\">Angular Elements, Part V: Your Options For Building Angular Elements With The CLI<\/a><\/li>\n<\/ul>\n<\/div>\n<hr>\n<p>Since Version 6, we can very easily create Web Components with Angular. To be more precise, we should speak about Custom Elements -- a standard behind the umbrella term Web Components that allows for creating own HTML-Elements.<\/p>\n<p>However, Angular depends on zone.js for Change Tracking and in most cases we don't want to force the consumers of our widgets into using it.<\/p>\n<p>In this short article, I explain why excluding zone.js is a good idea and how to deal with the consequences. The sample I use for this can be found in my <a href=\"https:\/\/github.com\/manfredsteyer\/angular-elements-dashboard\/tree\/noop-zone\">github repo<\/a>. Please make sure to use the branch <code>noop-zone<\/code>.<\/p>\n<h2 id=\"why-zonejs-might-be-a-bad-idea-for-custom-elements\">Why zone.js might be a bad idea for Custom Elements<\/h2>\n<p>In general, we want our custom elements to be as small as possible in terms of bundle size. The upcoming ngIvy view engine will help a lot with this goal as it produces more tree-shakable code and hence allows Angular \"blowing itself mostly away\" during the compilation.<\/p>\n<p>Another approach to shrink bundles is reusing Angular packages across several Angular Elements and the host application. After an enlightening discussion with Angular's <a href=\"https:\/\/twitter.com\/robwormald\">Rob Wormald<\/a>, I've created <a href=\"https:\/\/www.npmjs.com\/package\/ngx-build-plus\">ngx-build-plus<\/a> -- a simple CLI extension that helps to implement this idea.<\/p>\n<p>However, in both cases we cannot get rid of <code>zone.js<\/code> which is used by Angular for change tracking since its first days. This library monkey patches a lot of browser objects to get informed about all events after which Angular needs to check the displayed components for changes.<\/p>\n<p>While this provides convenience in Angular application, having such a dependency for a custom element is not desirable, especially when the hosting application is not Angular based: Not every consumer wants to monkey patch browser objects and in many cases <code>zone.js<\/code> is bigger than the custom element itself.<\/p>\n<h2 id=\"getting-rid-of-zonejs\">Getting rid of zone.js<\/h2>\n<p>Getting rid of <code>zone.js<\/code> is the easiest part. Just set configure the noop zone (no operation zone) when bootstrapping the Angular application:<\/p>\n<pre class=\"hljs\"><code><div>platformBrowserDynamic()\n   .bootstrapModule(\n       AppModule, { ngZone: <span class=\"hljs-string\">'noop'<\/span> })\n   .catch(err =&gt; <span class=\"hljs-built_in\">console<\/span>.log(err));\n<\/div><\/code><\/pre>\n<p>However, dealing with the consequences of removing <code>zone.js<\/code> isn't that easy as without this library we have to trigger change detection manually.<\/p>\n<h2 id=\"triggering-change-detection-manually\">Triggering Change Detection manually<\/h2>\n<p>For my demonstrations, I use a simple Angular component that displays three numeric values:<\/p>\n<pre class=\"hljs\"><code><div>@Component({\n  [...]\n})\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">class<\/span> ExternalDashboardTileComponent {\n\n  @Input() a: <span class=\"hljs-built_in\">number<\/span>;\n  @Input() b: <span class=\"hljs-built_in\">number<\/span>;\n  @Input() c: <span class=\"hljs-built_in\">number<\/span>;\n\n  more(): <span class=\"hljs-built_in\">void<\/span> {\n    <span class=\"hljs-keyword\">this<\/span>.a = <span class=\"hljs-built_in\">Math<\/span>.round(<span class=\"hljs-built_in\">Math<\/span>.random() * <span class=\"hljs-number\">100<\/span>);\n    <span class=\"hljs-keyword\">this<\/span>.b = <span class=\"hljs-built_in\">Math<\/span>.round(<span class=\"hljs-built_in\">Math<\/span>.random() * <span class=\"hljs-number\">100<\/span>);\n    <span class=\"hljs-keyword\">this<\/span>.c = <span class=\"hljs-built_in\">Math<\/span>.round(<span class=\"hljs-built_in\">Math<\/span>.random() * <span class=\"hljs-number\">100<\/span>);\n  }\n}\n<\/div><\/code><\/pre>\n<p>It also provides a <code>more<\/code> method that updates those values. For the sake of simplicity, I use random numbers here.<\/p>\n<p>The values are displayed in an table and the method is bound to the click event of a button:<\/p>\n<pre class=\"hljs\"><code><div><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"table table-condensed\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>A<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>{{a}}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>B<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>{{b}}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>C<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>{{c}}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">table<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-default btn-sm\"<\/span> (<span class=\"hljs-attr\">click<\/span>)=<span class=\"hljs-string\">\"more()\"<\/span>&gt;<\/span>More<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n<\/div><\/code><\/pre>\n<p>When using <code>zone.js<\/code>, Angular is automatically performing change detection after the click event and hence updating the bound values. But without <code>zone.js<\/code> Angular is not aware of the click event. This means, we have to trigger change detection by hand.<\/p>\n<p>This can be accomplished by calling the <code>markForCheck<\/code> method of the current <code>ChangeDetectorRef<\/code>:<\/p>\n<pre class=\"hljs\"><code><div>@Component({\n  [...]\n})\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">class<\/span> ExternalDashboardTileComponent {\n\n  @Input() a: <span class=\"hljs-built_in\">number<\/span>;\n  @Input() b: <span class=\"hljs-built_in\">number<\/span>;\n  @Input() c: <span class=\"hljs-built_in\">number<\/span>;\n\n  <span class=\"hljs-keyword\">constructor<\/span>(private cd: ChangeDetectorRef) {\n  }\n\n  more(): <span class=\"hljs-built_in\">void<\/span> {\n    <span class=\"hljs-keyword\">this<\/span>.a = <span class=\"hljs-built_in\">Math<\/span>.round(<span class=\"hljs-built_in\">Math<\/span>.random() * <span class=\"hljs-number\">100<\/span>);\n    <span class=\"hljs-keyword\">this<\/span>.b = <span class=\"hljs-built_in\">Math<\/span>.round(<span class=\"hljs-built_in\">Math<\/span>.random() * <span class=\"hljs-number\">100<\/span>);\n    <span class=\"hljs-keyword\">this<\/span>.c = <span class=\"hljs-built_in\">Math<\/span>.round(<span class=\"hljs-built_in\">Math<\/span>.random() * <span class=\"hljs-number\">100<\/span>);\n\n    <span class=\"hljs-keyword\">this<\/span>.cd.markForCheck();\n  }\n\n}\n<\/div><\/code><\/pre>\n<p>As this is a very explicit approach, one can easily forget about calling the method at the right moment. Therefore I present an alternative in the next section.<\/p>\n<h2 id=\"push-pipe\">Push-Pipe<\/h2>\n<p>A more declarative way for triggering change detection is using Observables. Every time a new value arises, a pipe can tell Angular to check for changes. While Angular comes with the <code>async<\/code> pipe for such cases, it also demands on <code>zone.js<\/code>.<\/p>\n<p>What we need is a tuned <code>async<\/code> pipe. A prototypical (!) one comes from <a href=\"https:\/\/github.com\/Toxicable\">Fabian Wiles<\/a> who is an active community member. He calls it <a href=\"https:\/\/raw.githubusercontent.com\/Toxicable\/angular\/798ce0b5288c7a8b522d1ca710a4f64e427e931c\/packages\/common\/src\/pipes\/push_pipe.ts\">push pipe<\/a>.<\/p>\n<p>To use it, we need to introduce an Observable. In my example, I put it directly into the component. In an more advanced case, it should be provided by a service instead. To be able to directly notify it, I'm using a <code>BehaviorSubject<\/code> too:<\/p>\n<pre class=\"hljs\"><code><div>@Component({\n   [...]\n})\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">class<\/span> ExternalDashboardTileComponent <span class=\"hljs-keyword\">implements<\/span> OnInit {\n\n  @Input() a: <span class=\"hljs-built_in\">number<\/span>;\n  @Input() b: <span class=\"hljs-built_in\">number<\/span>;\n  @Input() c: <span class=\"hljs-built_in\">number<\/span>;\n\n  <span class=\"hljs-keyword\">private<\/span> statsSubject = <span class=\"hljs-keyword\">new<\/span> BehaviorSubject&lt;Stats&gt;(<span class=\"hljs-literal\">null<\/span>);\n  <span class=\"hljs-keyword\">public<\/span> stats$ = <span class=\"hljs-keyword\">this<\/span>.statsSubject.asObservable();\n\n  [...]\n}\n<\/div><\/code><\/pre>\n<p>To get along with just one Observable for all three values, I group them with a class <code>Stats<\/code>:<\/p>\n<pre class=\"hljs\"><code><div><span class=\"hljs-keyword\">class<\/span> Stats {\n  <span class=\"hljs-keyword\">constructor<\/span>(\n    readonly a: number,\n    readonly b: number,\n    readonly c: number\n  ) { }\n}\n<\/div><\/code><\/pre>\n<p>After Angular created the component, we have to publish the three numeric values for the first time:<\/p>\n<pre class=\"hljs\"><code><div>ngOnInit(): <span class=\"hljs-built_in\">void<\/span> {\n  <span class=\"hljs-keyword\">this<\/span>.statsSubject.next(<span class=\"hljs-keyword\">new<\/span> Stats(<span class=\"hljs-keyword\">this<\/span>.a, <span class=\"hljs-keyword\">this<\/span>.b, <span class=\"hljs-keyword\">this<\/span>.c));\n}\n<\/div><\/code><\/pre>\n<p>After each modification, we have to do the same:<\/p>\n<pre class=\"hljs\"><code><div>more(): <span class=\"hljs-built_in\">void<\/span> {\n  <span class=\"hljs-keyword\">this<\/span>.a = <span class=\"hljs-built_in\">Math<\/span>.round(<span class=\"hljs-built_in\">Math<\/span>.random() * <span class=\"hljs-number\">100<\/span>);\n  <span class=\"hljs-keyword\">this<\/span>.b = <span class=\"hljs-built_in\">Math<\/span>.round(<span class=\"hljs-built_in\">Math<\/span>.random() * <span class=\"hljs-number\">100<\/span>);\n  <span class=\"hljs-keyword\">this<\/span>.c = <span class=\"hljs-built_in\">Math<\/span>.round(<span class=\"hljs-built_in\">Math<\/span>.random() * <span class=\"hljs-number\">100<\/span>);\n\n  <span class=\"hljs-keyword\">this<\/span>.statsSubject.next(<span class=\"hljs-keyword\">new<\/span> Stats(<span class=\"hljs-keyword\">this<\/span>.a, <span class=\"hljs-keyword\">this<\/span>.b, <span class=\"hljs-keyword\">this<\/span>.c));\n}\n<\/div><\/code><\/pre>\n<p>In the template, we can subscribe to the Observable with the new <code>push<\/code> pipe. In the next listing I'm using an ngIf for this. The as clause writes the received object into the <code>stats<\/code> template variable.<\/p>\n<pre class=\"hljs\"><code><div><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"content\"<\/span> *<span class=\"hljs-attr\">ngIf<\/span>=<span class=\"hljs-string\">\"stats$ | push as stats\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"height:200px;\"<\/span>&gt;<\/span> \n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">br<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">table<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"table table-condensed\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>A<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>{{stats.a}}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>B<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>{{stats.b}}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>C<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">td<\/span>&gt;<\/span>{{stats.c}}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">td<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">tr<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">table<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-default btn-sm\"<\/span> (<span class=\"hljs-attr\">click<\/span>)=<span class=\"hljs-string\">\"more()\"<\/span>&gt;<\/span>More<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/div><\/code><\/pre>\n<p>Also, we can switch to OnPush now, as we are just relying on Observables and Immutables:<\/p>\n<pre class=\"hljs\"><code><div>@Component({\n  [...],\n  changeDetection: ChangeDetectionStrategy.OnPush\n})\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">class<\/span> ExternalDashboardTileComponent <span class=\"hljs-keyword\">implements<\/span> OnInit {\n    [...]\n}\n<\/div><\/code><\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Angular Elements without Zone.Js<\/p>\n","protected":false},"author":9,"featured_media":3016,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2366","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-unkategorisiert"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Angular Elements, Part III - ANGULARarchitects<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular Elements, Part III - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"Angular Elements without Zone.Js\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2019-04-03T12:53:56+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/angular-elements-without-zone-js.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"640\" \/>\n\t<meta property=\"og:image:height\" content=\"480\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Manfred Steyer, GDE\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@daniel\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer, GDE\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/\"},\"author\":{\"name\":\"Manfred Steyer, GDE\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\"},\"headline\":\"Angular Elements, Part III\",\"datePublished\":\"2019-04-03T12:53:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/\"},\"wordCount\":751,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/angular-elements-without-zone-js.jpg\",\"articleSection\":[\"Unkategorisiert\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/\",\"name\":\"Angular Elements, Part III - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/angular-elements-without-zone-js.jpg\",\"datePublished\":\"2019-04-03T12:53:56+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/angular-elements-without-zone-js.jpg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/angular-elements-without-zone-js.jpg\",\"width\":640,\"height\":480},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular Elements, Part III\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951\",\"name\":\"Manfred Steyer, GDE\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer, GDE\"},\"sameAs\":[\"https:\/\/x.com\/daniel\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Angular Elements, Part III - ANGULARarchitects","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/","og_locale":"en_US","og_type":"article","og_title":"Angular Elements, Part III - ANGULARarchitects","og_description":"Angular Elements without Zone.Js","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/","og_site_name":"ANGULARarchitects","article_published_time":"2019-04-03T12:53:56+00:00","og_image":[{"width":640,"height":480,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/angular-elements-without-zone-js.jpg","type":"image\/jpeg"}],"author":"Manfred Steyer, GDE","twitter_card":"summary_large_image","twitter_creator":"@daniel","twitter_misc":{"Written by":"Manfred Steyer, GDE","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/"},"author":{"name":"Manfred Steyer, GDE","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951"},"headline":"Angular Elements, Part III","datePublished":"2019-04-03T12:53:56+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/"},"wordCount":751,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/angular-elements-without-zone-js.jpg","articleSection":["Unkategorisiert"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/","name":"Angular Elements, Part III - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/angular-elements-without-zone-js.jpg","datePublished":"2019-04-03T12:53:56+00:00","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/angular-elements-without-zone-js.jpg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2019\/04\/angular-elements-without-zone-js.jpg","width":640,"height":480},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/angular-elements-part-iii\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"Angular Elements, Part III"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/15628efa7af4475ffaaeeb26c5112951","name":"Manfred Steyer, GDE","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a0b59539674d8b71ea1c1f4764b11244b5f499203f1d11b40f37d8f3f90be033?s=96&d=mm&r=g","caption":"Manfred Steyer, GDE"},"sameAs":["https:\/\/x.com\/daniel"]}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/2366","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=2366"}],"version-history":[{"count":0,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/2366\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/3016"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=2366"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=2366"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=2366"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}