<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stefano Marchisio (sviluppatore freelance)</title>
    <description>The latest articles on DEV Community by Stefano Marchisio (sviluppatore freelance) (@mastefano64).</description>
    <link>https://dev.to/mastefano64</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F519380%2Fa694cca7-9610-4bd9-a9ef-dd908ee28e81.jpeg</url>
      <title>DEV Community: Stefano Marchisio (sviluppatore freelance)</title>
      <link>https://dev.to/mastefano64</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mastefano64"/>
    <language>en</language>
    <item>
      <title>Introduzione ad Angular</title>
      <dc:creator>Stefano Marchisio (sviluppatore freelance)</dc:creator>
      <pubDate>Tue, 02 Feb 2021 20:34:23 +0000</pubDate>
      <link>https://dev.to/mastefano64/introduzione-ad-angular-5ba7</link>
      <guid>https://dev.to/mastefano64/introduzione-ad-angular-5ba7</guid>
      <description>&lt;p&gt;&lt;a href="https://www.stefanomarchisio.it/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  In questo Angular tutorial verranno trattati: Data Binding | decoratori @Input, @Output | decoratori @ViewChild, @ViewChildren, @ContentChild, @ContentChildren | content projection | manipolazione del DOM
&lt;/h4&gt;

&lt;p&gt;Angular è un framework per lo sviluppo di SPA a componenti ed è una riscrittura completa di AngularJS. È stato rilasciato per la prima volta a maggio 2016 e la versione finale è stata rilasciata il 14 settembre 2016.&lt;/p&gt;

&lt;p&gt;Angular ha molti miglioramenti rispetto ad AngularJS e presenta molte innovazioni che semplificano l'apprendimento e lo sviluppo di applicazioni enterprise.&lt;/p&gt;

&lt;p&gt;In un applicazione Angular ogni elemento che vediamo nella UI è un component, ed un componente può essere a sua volta inserito all’interno di un altro componente formando così una struttura ad albero. In fase di progettazione è necessario quindi, scomporre la UI che desideriamo costruire in sotto componenti che svolgono una specifica funzione. Questo facilità in seguito eventuali modifiche oltre al riutilizzo del codice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZBL4pp8u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a302ml5s8qria7t7p8u2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZBL4pp8u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a302ml5s8qria7t7p8u2.png" alt="Alt Text" width="880" height="662"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Il presente articolo è una raccolta di link che introducono e trattano alcuni aspetti base di Angular ( &lt;a href="https://www.stefanomarchisio.it/angular-typescript-javascript-rxjs1.pptx"&gt;Slide&lt;/a&gt; - &lt;a href="https://github.com/mastefano64"&gt;GitHub&lt;/a&gt; ).&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://dev.to/mastefano64/angular-component-communication-data-binding-parte-1-321h"&gt;Angular Component Communication (Data Binding) – parte 1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) &lt;a href="https://dev.to/mastefano64/angular-component-communication-decoratori-input-output-parte-2-368f"&gt;Angular Component Communication (decoratori @Input, @Output) – parte 2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-template-reference-variable-e-i-decoratori-viewchild-viewchildren-contentchild-contentchildren-in-angular-2a7d"&gt;Cosa sono le Template Reference Variable e i decoratori @ViewChild @ViewChildren @ContentChild @ContentChildren in Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-projection-in-angular-ng-content-contentchild-contentchildren-aml"&gt;Cosa sono le “projection” in Angular (ng-content ContentChild ContentChildren)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5) &lt;a href="https://dev.to/mastefano64/come-manipolare-il-dom-da-un-applicazione-angular-2oj5"&gt;Come manipolare il DOM da un applicazione Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ogni componente Angular ha poi degli eventi che vengono scatenati in determinati momenti, per esempio quando vengono inizializzate le proprietà di input piuttosto che quando il componente ed i relativi figli sono stati creati. E' opportuno utilizzare gli eventi del life-cycle di un componente nel modo appropriato onde evitare di incorrere in errori, maggiori informazioni al riguardo le potete trovare &lt;a href="https://www.linkedin.com/pulse/expressionchangedafterithasbeencheckederror-perch%C3%A9-accade-marchisio"&gt;qui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8tCszxuc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mqpusnl3x21f6w5ns7hv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8tCszxuc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mqpusnl3x21f6w5ns7hv.png" alt="Alt Text" width="825" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se volete contattarmi il mio profilo Linkedin è il seguente:&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/stefano-marchisio-sviluppatore-web-angular-javascript-aspnet-fullstack/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Come manipolare il DOM da un applicazione Angular</title>
      <dc:creator>Stefano Marchisio (sviluppatore freelance)</dc:creator>
      <pubDate>Tue, 02 Feb 2021 17:25:15 +0000</pubDate>
      <link>https://dev.to/mastefano64/come-manipolare-il-dom-da-un-applicazione-angular-2oj5</link>
      <guid>https://dev.to/mastefano64/come-manipolare-il-dom-da-un-applicazione-angular-2oj5</guid>
      <description>&lt;p&gt;&lt;a href="https://www.stefanomarchisio.it/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Quest'articolo spiega come manipolare il DOM in Angular attraverso le “Directive attributo” e le “Directive strutturali” piuttosto che lavorare a basso livello usando “Renderer2” e “ViewContainer” (ElementRef, TemplateRef, ViewContainerRef)
&lt;/h4&gt;

&lt;h2&gt;
  
  
  Introduzione
&lt;/h2&gt;

&lt;p&gt;In un ottica web un developer è abituato a manipolare il DOM in un certo modo. Per esempio, creando lato client del codice HTML per poi inserirlo nel DOM tramite delle API JQuery, piuttosto che fare una chiamata AJAX che ci restituisca del codice HTML. Esiste poi l’opzione di far ritornare dati in formato JSON che verranno poi renderizzati tramite una delle tante librerie di template. Con Angular la manipolazione del DOM non avviene in questo modo, questo può essere causa di disagio soprattutto all’inizio in cui uno inizia a lavorare con Angular. In quest’articolo vediamo il perché, e come possiamo fare a manipolare il DOM utilizzando le API fornite da Angular.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y_0eFm6H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3nno7fcx28nlhqgg2y55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y_0eFm6H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3nno7fcx28nlhqgg2y55.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Iniziamo col dire che Angular è un framework a componenti e di solito troviamo 3 file per ogni componente: un file .ts , un file .css e un file .html che rappresenta il template del componente. All’interno del template oltre all’HTML classico troviamo anche degli attributi/direttive di binding che servono a legare il template HTML al file TypeScript corrispondente, in questo modo la UI verrà automaticamente aggiornata nel momento in cui si cambia il valore di una delle proprietà del file TypeScript. &lt;/p&gt;

&lt;p&gt;Per questo motivo altre alla compilazione TypeScript esiste anche una seconda compilazione Angular. Infatti in Angular è presente anche un compilatore, e questa può avvenire in modalità JIT piuttosto che AOT. Lo scopo di tale compilazione è tradurre l’HTML e gli attributi/direttive di binding presenti nel template in qualche cosa comprensibile dal framework. Senza entrare troppo nel dettaglio per ogni componente viene anche creata una classe di “ChangeDetection” che rileva eventuali modifiche (confrontando i vecchi valori con i nuovi), al verificarsi ci certi eventi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Da questo si evince che il DOM è generato da queste classi&lt;/strong&gt; (che non sono direttamente utilizzate dallo sviluppatore). &lt;strong&gt;Inoltre il collegamento tra questa famiglia di classi ed il DOM è unidirezionale&lt;/strong&gt;, infatti se manipolo il DOM alla vecchia maniera (per esempio eliminando un nodo), la classe di “ChangeDetection” corrispondente non se ne accorge e continua a fare il suo lavoro. Ciò alla lunga può causare dei problemi di vario genere (in particolar modo prestazionali).&lt;/p&gt;

&lt;p&gt;Tutto questo per spiegare il perché con Angular si deve procedere in modo diverso nella manipolazione del DOM da come siamo abituati a fare di solito. Nello stesso tempo Angular fornisce diversi strumenti/API per lavorare con il DOM in modo sicuro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Come facciamo
&lt;/h2&gt;

&lt;p&gt;In Angular abbiamo 2 strade per fa ciò&lt;/p&gt;

&lt;p&gt;1) Usare le “Attribute directive” e “Structural directive” buld-in all’interno del framework che rendono tale cosa estremamente semplice&lt;/p&gt;

&lt;p&gt;2) Lavorare ad un livello più basso usando: “Renderer2” e “ViewContainer&lt;/p&gt;

&lt;h2&gt;
  
  
  Direttive “Attribute directive” e “Structural directive”
&lt;/h2&gt;

&lt;p&gt;In Angular esistono 2 famiglie di direttive buld-in che servono per manipolare il DOM in modo semplice e sicuro, ognuna di queste 2 famiglie è poi specializza per lavorare con gli attributi di un elemento piuttosto che aggiungere o rimuovere elementi.&lt;/p&gt;

&lt;p&gt;Le “Attribute directive” appartengono alla prima famiglia e servono per lavorare con gli attributi di un elemento. In Angular ne esistono 2: “ngClass” e “ngStyle”. Con la prima è possibile aggiungere o rimuovere classi css da un elemento, con la seconda e possibile creare o rimuovere proprietà css da un elemento. Ogni direttiva può poi essere messa in binding con una proprietà all’interno del file TypeScript, in modo che i valori vengano settati in modo dinamico (sotto un esempio di ngClass).  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cc9LE1Am--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yehe6wz40onmr62i96t8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cc9LE1Am--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yehe6wz40onmr62i96t8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Le “Structural directive” appartengono alla seconda famiglia e servono per aggiungere o rimuovere elementi dal DOM. In Angular ne esistono 3: “ngIf”, “ngFor”, “ngSwitch”. Come si evince dal nome, con la prima è possibile creare degli elementi in modo condizionale, con la seconda è possibile renderizzare una lista di elementi, con la terza è possibile creare degli elementi in modo condizionale tramite un’istruzione di switch. Tutte le direttive strutturali possono essere messe in binding con proprietà contenute all’interno del file TypeScript (sotto un paio di esempi).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X1RZ8_97--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vef02htjk3yz651re3yp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X1RZ8_97--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vef02htjk3yz651re3yp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può notare le direttive strutturali sono precedute con un “*” davanti al nome, infatti vengono scritte come: *ngIf, *ngFor, *ngSwitchCase (questa è una “syntax sugar”). Come detto all’inizio dell’articolo, oltre alla compilazione TypeScript esiste anche una seconda compilazione Angular che lavora principalmente sui template HTML.&lt;/p&gt;

&lt;p&gt;Una direttiva “ngIf” come quella sottostante&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EABEVsUw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6rfwofq9w7r4pzxiie8t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EABEVsUw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6rfwofq9w7r4pzxiie8t.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Viene tradotta in questo modo dal compilatore&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dHj9rRUO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n27bctrybz3y1j9nspzn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dHj9rRUO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n27bctrybz3y1j9nspzn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Questo per rendere più agevole la scrittura di codice, ma se scrivessimo un “ngIf” nel secondo formato il tutto funzionerebbe senza problemi. Per maggiori informazioni in merito alle direttive build-in si rimanda alla documentazione del framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  “Renderer2” e “ViewContainer”
&lt;/h2&gt;

&lt;p&gt;Fino ad ora abbiamo visto come possiamo manipolare il DOM usando le direttive build-in presenti nel framework, ma nel caso queste non bastassero dobbiamo iniziare a lavorare ad un livello più basso ed è in questo caso che entrano in gioco “Rendere2” e “ViewContainer”.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Rendere2”&lt;/em&gt; viene usato quando vogliamo lavorare con gli attributi di un elemento.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“ViewContainer”&lt;/em&gt; viene usato quando vogliamo aggiungere o rimuovere degli elementi.&lt;/p&gt;

&lt;p&gt;Prima di continuare dobbiamo fare una premessa per capire meglio quello che verrà dopo. Abbiamo detto che Angular è un “framework per lo sviluppo di applicazioni web” più comunemente dette SPA. Gli sviluppatori di Angular non si sono solo prefissati che un applicazione possa essere eseguita all’interno del browser, ma che possa anche essere eseguita in un web-workers o server-side. Detto ciò, in alcuni momenti un browser come lo intendiamo noi potrebbe non essere presente, per cui hanno introdotto una serie di astrazioni e “Render2” è appunto una di queste.&lt;/p&gt;

&lt;h2&gt;
  
  
  “Renderer2”
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;ElementRef&lt;/em&gt;: fornisce una referenza ad un elemento del DOM, può essere iniettato nel costruttore di un componet / directive oppure letto tramite: @ViewChild(), @ViewChildren. Nel caso la iniettiamo nel costruttore di una direttiva fornisce una referenza all’elemento sul quale la direttiva è applicata.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Rendere2&lt;/em&gt;: è un astrazione al DOM per non incorrere agli effetti server-side o web-workers, di norma tale classe è iniettata nel costruttore di un componet / directive.&lt;/p&gt;

&lt;p&gt;Queste classi lavorano insieme (Rendere2 lavora sul DOM mentre ElementRef è una referenza ad un elemento del DOM). Sotto possiamo vedere il codice di una semplice direttiva.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3gscf2XA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/29uvxv71uaqac2skp8x1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3gscf2XA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/29uvxv71uaqac2skp8x1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere manipolare il DOM con “Rendere2” non è più complicato che manipolare il DOM direttamente, inoltre “Rendere2” contiene una serie metodi con i quali è possibile effettuare le principali operazioni sugli attributi: setAttribute(), removeAttribute(), addClass(), removeClass(), setStyle(), removeStyle().&lt;/p&gt;

&lt;h2&gt;
  
  
  “ViewContainer”
&lt;/h2&gt;

&lt;p&gt;La prima cosa da dire è che ogni elemento del DOM può essere usato come ViewContainer, inoltre Angular non inserisce il contenuto all’interno di un ViewContainer ma lo appende dopo. Un candidato ideale come ViewContainer può essere l’elemento “ng-container”, questo perché viene renderizzato come commento evitando di inserire nel DOM elementi ritondanti. Un ViewContainer possiede vari metodi tra cui: createEmbeddedView() e createComponent(). Con questi metodi è possibile creare EmbeddedView e HostView, le prime sono create usando come modello un “Template” le seconde sono create usando come modello un “Component”.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ViewContainerRef&lt;/em&gt;: rappresenta un contenitore o placeholder dove una o più viste possono essere attaccate. Può essere iniettato nel costruttore oppure letto tramite: @ViewChild(), @ViewChildren(). Se iniettato nel costruttore di un componente, rappresenta il componente stesso.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;TemplateRef&lt;/em&gt;: rappresenta il template con cui è possibile creare un EmbeddedView. Può essere iniettato nel costruttore (nel caso si tratti di una direttiva custum) oppure letto tramite: @ViewChild(), @ViewChildren().&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sotto si può vedere un esempio di codice di un EmbeddedView (ovvero view che usano come modello un template).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lK028N55--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9pt5qo40izghqgpta22i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lK028N55--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9pt5qo40izghqgpta22i.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere abbiamo un div / #container1 ed un template #tpl1. All’interno del componente tramite @ViewChild() vengono lette le reference di questi 2 elementi e all’interno del metodo ngAfterViewInit() viene creata l’EmbeddedView tramite il metodo this.vcr1.createEmbeddedView(this.tpl1). Da notare che l’ EmbeddedView è stata creata all’interno del metodo ngAfterViewInit() perché le reference recuperate tramite @ViewChild() sono disponibili dopo questo evento, prima avrebbero valore undfined se stiamo usando componenti dinamici. Con Angular 8 le cose cambiano leggermente, maggiori informazioni &lt;a href="https://angular.io/guide/static-query-migration"&gt;quì&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;Ciò vale tutte le volte che si utilizza @ViewChild(), @ViewChildren (), etc. In questo modo il codice HTML contenuto nel template viene inserito in modo sicuro all’interno del DOM. La classe ViewContainer fornisce inoltre una serie di altri metodi tra cui clear(), con cui è possibile rimuovere il codice HTML del template dal DOM. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sotto si può vedere un esempio di codice di un EmbeddedView (ovvero view che usano come modello una direttiva strutturale custom).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ybQqT3Wk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bj5ubfv9fd2r4v4y7utn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ybQqT3Wk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bj5ubfv9fd2r4v4y7utn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere, all’interno del nostro componente abbiamo 2 bottoni (uno per creare e l’altro per rimuovere) ed una direttiva strutturale custom contenuta in un div.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JXqFHwM4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hvnd8zj21ocfhnvqplt8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JXqFHwM4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hvnd8zj21ocfhnvqplt8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come menzionato sopra, la direttiva viene tradotta dal compilatore in questo modo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U2MaGzan--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6bgx1dsbpwofefr533da.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U2MaGzan--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6bgx1dsbpwofefr533da.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All’interno del codice TypeScript della direttiva, vengono iniettati nel costruttore il ViewContainerRef ed il TemplateRef. In questo modo quando premiamo i bottoni di creazione e rimozione vengono chiamati rispettivamente i metodi del ViewContainer: this.vcr.createEmbeddedView(this.tpl) e this.vcr.clear(). Come si può vedere il codice di una direttiva strutturale è abbastanza simile al codice utilizzato per creare un EmbeddedView all’interno di un componente. Il vantaggio è che in questo modo ho un maggior riutilizzo del codice oltre al fatto di separare le responsabilità Component / Directive.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sotto si può vedere un esempio di codice di un HostView (ovvero view che usano come modello un Component).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lrM2dQBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8a8abw1jw500dl941qpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lrM2dQBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8a8abw1jw500dl941qpn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In questo esempio abbiamo scelto di utilizzare come modello un componente (ovvero vogliamo creare un HostView). Non essendo possibile istanziare il componente direttamente con una new dobbiamo crearlo utilizzando la factory relativa al componete. Per far ciò, all’interno del costruttore iniettiamo il servizio “ComponentFactoryResolver” e poi tramite questo servizio creiamo la factory del componente che vogliamo creare. Infine tramite il metodo createComponent(factory) del viewcontainer creiamo il nostro componente passando come parametro la factory appena creata. In questo modo il codice HTML contenuto nel componente viene inserito in modo sicuro all’interno del DOM. La classe ViewContainer fornisce inoltre una serie di altri metodi tra cui clear(), con cui è possibile rimuovere il codice dal DOM.&lt;/p&gt;

&lt;h2&gt;
  
  
  ngTemplateOutlet e NgComponentOutlet
&lt;/h2&gt;

&lt;p&gt;Fino ad ora abbiamo utilizzato le api fornite da ViewContainerRef: createEmbeddedView() e createComponent();  per creare EmbeddedView e HostView utilizzando un approccio imperativo da codice, ma Angular ci mette anche a disposizione delle direttive strutturali per fare la stessa cosa in modo dichiarativo. Queste direttive sono usate frequentemente con ng-container, ma possono anche essere applicate ad un elemento html.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--De8iGnFP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mpdst8d4wcn9qiunxvd0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--De8iGnFP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mpdst8d4wcn9qiunxvd0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In questo esempio è stata utilizzata la direttiva “ngTemplateOutlet” all’interno di un ng-container, passando come parametro la template reference variable che identifica il template da renderizzare. Come si può vedere non è stato necessario utilizzare nessuna delle api degli esempi precedenti, rendendo la cosa molto più veloce! Anche se non mostrato nell’esempio, è anche possibile definire e passare al template un context contenente delle variabili.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--498_juJv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6c6yqjwj5aqidwv19cme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--498_juJv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6c6yqjwj5aqidwv19cme.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In questo esempio è stata utilizzata la direttiva “ngComponentOutlet” all’interno di un ng-container, passando come parametro la variabile compfirst tipizzata come CompFirstComponent. Come si può vedere non è stato necessario utilizzare nessuna delle api degli esempi precedenti, rendendo la cosa molto più veloce! Anche se non mostrato nell’esempio, è anche possibile definire e passare al componente che verrà creato un injector sul quale sono stati registrati dei servizi.&lt;/p&gt;

&lt;p&gt;Come si può vedere l’utilizzo delle direttive strutturali “ngTemplateOutlet” e “ngComponentOutlet” permettono la creazione di EmbeddedView e HostView in modo dichiarativo, senza la necessità di richiamare le api degli esempi precedenti.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusioni
&lt;/h2&gt;

&lt;p&gt;Fino ad ora sono state utilizzate le API presenti nel framework. Cose analoghe possono anche essere fatte utilizzando gli &lt;a href="https://www.linkedin.com/pulse/come-creare-un-overlay-usando-angular-material-cdk-stefano-marchisio/"&gt;“Overlay” presenti in “Angular Material”&lt;/a&gt;, ma non è lo scopo di quest’articolo.&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://dev.to/mastefano64/introduzione-ad-angular-5ba7"&gt;Introduzione ad Angular / Sommario&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) &lt;a href="https://dev.to/mastefano64/angular-component-communication-data-binding-parte-1-321h"&gt;Angular Component Communication (Data Binding) – parte 1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) &lt;a href="https://dev.to/mastefano64/angular-component-communication-decoratori-input-output-parte-2-368f"&gt;Angular Component Communication (decoratori @Input, @Output) – parte 2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-template-reference-variable-e-i-decoratori-viewchild-viewchildren-contentchild-contentchildren-in-angular-2a7d"&gt;Cosa sono le Template Reference Variable e i decoratori @ViewChild @ViewChildren @ContentChild @ContentChildren in Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-projection-in-angular-ng-content-contentchild-contentchildren-aml"&gt;Cosa sono le “projection” in Angular (ng-content ContentChild ContentChildren)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6) &lt;a href="https://dev.to/mastefano64/come-manipolare-il-dom-da-un-applicazione-angular-2oj5"&gt;Come manipolare il DOM da un applicazione Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se volete contattarmi il mio profilo Linkedin è il seguente:&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/stefano-marchisio-sviluppatore-web-angular-javascript-aspnet-fullstack/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Angular Component Communication (Data Binding) – parte 1</title>
      <dc:creator>Stefano Marchisio (sviluppatore freelance)</dc:creator>
      <pubDate>Tue, 02 Feb 2021 17:24:56 +0000</pubDate>
      <link>https://dev.to/mastefano64/angular-component-communication-data-binding-parte-1-321h</link>
      <guid>https://dev.to/mastefano64/angular-component-communication-data-binding-parte-1-321h</guid>
      <description>&lt;p&gt;&lt;a href="https://www.stefanomarchisio.it/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Quest'articolo mostra i 4 tipi di databinding presenti in Angular: Iterpolation, Property binding, Event binding, TwoWay binding
&lt;/h4&gt;

&lt;p&gt;Angular è un framework per lo sviluppo di SPA a componenti. Di solito un componente è composto da 3 files: un file .ts , un file .css e un file .html che contiene il template HTML del componente, ma volendo è anche possibile definire tutto in un unico file .ts, sarà responsabilità dello sviluppatore scegliere l’approccio che preferisce. &lt;em&gt;Per cui ogni elemento che vediamo nella UI è un componente ed un componente può essere a sua volta inserito all’interno di un altro componente, formando così una struttura ad albero.&lt;/em&gt; In fase di progettazione è necessario quindi, scomporre la UI che desideriamo costruire in sotto componenti che svolgono una specifica funzione. Questo facilità in seguito eventuali modifiche oltre al riutilizzo del codice. Eventualmente, se il progetto è di grandi dimensioni, è buona norma implementare anche pattern architetturali (per esempio stateful e stateless component).&lt;/p&gt;

&lt;p&gt;Si ha quindi la necessità che i componenti possano comunicare tra loro:&lt;/p&gt;

&lt;p&gt;1) Che il templete HTML possa comunicare con il codice TypeScript del componente corrispondente.&lt;/p&gt;

&lt;p&gt;2) Un componente padre possa inviare dati a componenti figlio, così come un componente figlio possa inviare dati al componente padre sotto forma di eventi.&lt;/p&gt;

&lt;p&gt;3) Che 2 o più componenti disgiunti possano inviarsi notifiche contenenti dati (RxJs Subject).&lt;/p&gt;

&lt;p&gt;In questa serie di articoli vedremo i vari strumenti che Angular ci fornisce per fare ciò, iniziando con il “data binding”, per passare poi ai decoratori di ”@Input” “@Output” ed infine alle “Template Reference Variable”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Binding
&lt;/h2&gt;

&lt;p&gt;Con data binding si intende la capacità di un template HTML di comunicare con il codice TypeScript del componente corrispondente, in modo che la UI verrà automaticamente aggiornata nel momento in cui si modifica il valore di una delle proprietà nel file TypeScript.&lt;/p&gt;

&lt;p&gt;A prescindere da Angular, esistono 2 modalità di comunicazione a seconda che questa avvenga in modo unidirezionale (“one way data binding”) o bidirezionale (“two way data binding”).&lt;/p&gt;

&lt;p&gt;1) Nel data binding unidirezionale o (“one way data binding”) i dati viaggiano dal modello al template. Aggiornando una proprietà nel modello viene aggiornata in modo automatico l’interfaccia utente.&lt;/p&gt;

&lt;p&gt;2) Nel data binding bidirezionale o (“two way data binding”) i dati viaggiano in entrambe le direzioni. Aggiornando una proprietà nel modello viene aggiornata in modo automatico l’interfaccia utente. Editando un elemento sull’interfaccia utente viene aggiornato il modello sottostante.&lt;/p&gt;

&lt;p&gt;In Angular abbiamo a disposizione 4 tipi di data binding: Iterpolation, Property binding, Event binding, TwoWay binding. I primi 3 tipi di data binding sono unidirezionali, il quarto tipo di data binding è bidirezionale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hs6fjNMM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pslsbo8a7pe7xkkz6utf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hs6fjNMM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pslsbo8a7pe7xkkz6utf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NGhJkAl7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6qg2327st6l4td3fs72k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NGhJkAl7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6qg2327st6l4td3fs72k.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Interpolation data binding
&lt;/h2&gt;

&lt;p&gt;L’ Intepolation data binding usa la seguente sintassi "{  { expression }  }" per renderizzare all' interno del template HTML dati presenti nel modello. Con "expression" si intende sia una semplice proprietà presente nel codice TypeScript del componente, che un espressione JavaScript valida.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tuAROwz6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d7a6cl2znuakyw6x9v8m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tuAROwz6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d7a6cl2znuakyw6x9v8m.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Property data binding
&lt;/h2&gt;

&lt;p&gt;Il property data binding usa la seguente sintassi “[]” per mettere in collegamento il template HTML con il modello. Viene utilizzato per mettere in comunicazione una proprietà di un elemento HTML (o di un nostro componente) con una proprietà presente nel codice TypeScript del componente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hN-Hnw-H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/urzxyjjpvpix4bprwuca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hN-Hnw-H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/urzxyjjpvpix4bprwuca.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interpolation data binding può essere un alternativa al property binding. Angular trasla interpolation data binding nel property data binding nel momento in cui compila il template HTML.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event data binding
&lt;/h2&gt;

&lt;p&gt;Quando un utente interagisce con la UI di un applicazione (muove il mouse, preme un tasto o un bottone) genera un evento, quest' evento deve poi essere intercettato e gestito nel codice TypeScript del componente. Angular fornisce inoltre la possibilità di creare eventi custom. I’ event data binding usa la seguente sintassi “()” per mettere in collegamento il template HTML con il modello.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8PFn317S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eoor0rs99f9thcctykec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8PFn317S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eoor0rs99f9thcctykec.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nell’esempio sovrastante si può vedere che l’evento che si desidera intercettare è tra parentesi tonde (a differenza del property data binding in cui si usavano le parentesi quadre). Tra doppi apici viene poi messo il metodo che deve essere chiamato, ed il parametro “$event” è una parola riservata di Angular e serve per passare l’evento originale al metodo (nel nostro caso MouseEvent).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3C1iThhX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u4u7h11ejaintl35xzyq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3C1iThhX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u4u7h11ejaintl35xzyq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L’esempio sovrastante è simile al precedente, l’unica differenza è che non viene passato “$event” come parametro ma bensì “car”. Infatti è anche possibile passare ad un event-handler una proprietà di data binding visibile dal template. Nel nostro esempio è presente un ciclo for che itera su una collezione cars. Per ogni elemento viene creato un bottone passando all’ event-handler l'oggetto car.&lt;/p&gt;

&lt;h2&gt;
  
  
  TwoWay data binding
&lt;/h2&gt;

&lt;p&gt;TwoWay data binding usa la seguente sintassi "[()]" per renderizzare all’interno del template HTML i dati presenti nel modello ed aggiornare il modello nel momento in cui si edita l’interfaccia. Come si può vedere non è altro che l’insieme delle 2 sintassi (Property data binding e Event data binding ). Per poterlo utilizzare dobbiamo usare la direttiva “ngModel” contenuta nel modulo “FormsModule”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AdBvIQqp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/s21y96ak7y7i96290b7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AdBvIQqp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/s21y96ak7y7i96290b7t.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere tra parentesi (quadrate e tonde) non si mette più la proprietà, ma la direttiva “ngModel”. La proprietà viene invece assegnata a ciò che abbiamo appena scritto e nel codice TypeScript del componente deve essere presente una proprietà “myfield”. In Angular il twoWay data binding non è poi così strategico perché esistono anche altre strade per poter aggiornare in dati.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z_K9GVdZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bf4r3w0883u2mmc1wqyk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z_K9GVdZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bf4r3w0883u2mmc1wqyk.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nell’esempio sovrastante all'evento "ngSubmit" è stata assegnata la funzione onSubmit(f) e come parametro viene passata la “Template Reference Variable” contenente direttiva ngForm. Questo mi servirà per recuperare i valori dei campi del form nel codice TypeScript del componente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e7OSB7QL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yaeorthx655qk5ovc8iq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e7OSB7QL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yaeorthx655qk5ovc8iq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nell’esempio compare anche una nuova sintassi: #f="ngForm". Questa è una “Template Reference Variable” e verranno trattate più avanti in questa serie di articoli.&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://dev.to/mastefano64/introduzione-ad-angular-5ba7"&gt;Introduzione ad Angular / Sommario&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) &lt;a href="https://dev.to/mastefano64/angular-component-communication-data-binding-parte-1-321h"&gt;Angular Component Communication (Data Binding) – parte 1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) &lt;a href="https://dev.to/mastefano64/angular-component-communication-decoratori-input-output-parte-2-368f"&gt;Angular Component Communication (decoratori @Input, @Output) – parte 2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-template-reference-variable-e-i-decoratori-viewchild-viewchildren-contentchild-contentchildren-in-angular-2a7d"&gt;Cosa sono le Template Reference Variable e i decoratori @ViewChild @ViewChildren @ContentChild @ContentChildren in Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-projection-in-angular-ng-content-contentchild-contentchildren-aml"&gt;Cosa sono le “projection” in Angular (ng-content ContentChild ContentChildren)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6) &lt;a href="https://dev.to/mastefano64/come-manipolare-il-dom-da-un-applicazione-angular-2oj5"&gt;Come manipolare il DOM da un applicazione Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se volete contattarmi il mio profilo Linkedin è il seguente:&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/stefano-marchisio-sviluppatore-web-angular-javascript-aspnet-fullstack/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Cosa sono le “projection” in Angular (ng-content ContentChild ContentChildren)</title>
      <dc:creator>Stefano Marchisio (sviluppatore freelance)</dc:creator>
      <pubDate>Tue, 02 Feb 2021 17:05:13 +0000</pubDate>
      <link>https://dev.to/mastefano64/cosa-sono-le-projection-in-angular-ng-content-contentchild-contentchildren-aml</link>
      <guid>https://dev.to/mastefano64/cosa-sono-le-projection-in-angular-ng-content-contentchild-contentchildren-aml</guid>
      <description>&lt;p&gt;&lt;a href="https://www.stefanomarchisio.it/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Quest'articolo spiega il concetto di projection in Angular, l'uso del tag ng-content e come recuperare il contenuto proiettato attraverso i decoratori: @ContentChild @ContentChildren
&lt;/h4&gt;

&lt;p&gt;Angular è un framework per sviluppare SPA a componenti. Ogni elemento che vediamo nella UI è un componente ed un componente a sua volta può essere inserito all’interno di un altro componente formando una struttura ad albero. Le projection sono un concetto molto importante in Angular, e servono a creare componenti scalabili e flessibili.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sCv0x_ew--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f4kp8qy7zvjbzoxq0vzf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sCv0x_ew--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f4kp8qy7zvjbzoxq0vzf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere abbiamo definito un semplice componente Angular che può essere riutilizzato tutte le volte che vogliamo inserendo il selettore &amp;lt; app-home&amp;gt; &amp;lt; /app-home&amp;gt; in un templete HTML. Come si può notare, pur avendo creato un componente riutilizzabile, non è molto flessibile perché le 2 righe di testo contenute nel template sono fisse così come i tag HTML. Per rendere la cosa più dinamica possiamo trasformarlo nel seguente modo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ktR-xoLe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eyv0shdbb353urn9a3zo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ktR-xoLe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eyv0shdbb353urn9a3zo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere il testo è diventato dinamico, infatti viene passato tramite proprietà di input nel selettore &amp;lt; app-home&amp;gt; &lt;br&gt;
&amp;lt; /app-home&amp;gt;. Il problema è che title e content hanno i rispettivi tag HTML,definiti all’interno del template dell’ HomeComponent, che rimangono fissi. Come possiamo fare se vogliamo che il title in alcuni casi sia visualizzato con H1 ed in altri con H2? Senza inserire delle istruzioni condizionali all’interno del template dell’ HomeComponent. La risposta è utilizzare le Angular “projection”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JlI0ahxh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i3nsc5kvogepd8xtl01n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JlI0ahxh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i3nsc5kvogepd8xtl01n.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere, oltre a passare dei dati ad un componente attraverso i parametri di input ( quelli definiti col decoratore @Input() ) è anche possibile passarli inserendoli tra il tag di aperture e chiusura di un componente. All’interno del componente troveremo poi un nuovo tag &amp;lt; ng-content&amp;gt; &amp;lt; /ng-content&amp;gt;. &lt;strong&gt;Questo nuovo tag è un placeholder ovvero definisce la posizione in cui inserire “testo” passato tra il tag di apertura e chiusura di un component.&lt;/strong&gt; Ho detto “testo”, ma può anche essere uno spezzone di codice HTML composto da più tag, piuttosto che un altro componente angular. In quest’ esempio il content continua ad essere passato come parametro di input. Come possiamo fare invece per passare sia title che content all’interno del tag di apertura e chiusura?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2__u8Vic--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8d0b0vo7jrktfwxsi2hd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2__u8Vic--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8d0b0vo7jrktfwxsi2hd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere troviamo ora 2 ng-content, il tag ng-content possiede un attributo addizionale “select” che funziona in modo analogo ad un selettore CSS. Per cui ogni ng-content visualizzerà solo gli elementi che soddisfano il criterio specificato, che nel nostro caso è h1 e span. Essendo simile ad un selettore CSS funziona anche con classi CSS. &lt;strong&gt;Con questi semplici esempi abbiamo spiegato quello che in Angular è chiamato “projection”.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nell’articolo riguardante le “Template Reference Variable” abbiamo introdotto i decoratori: @ViewChild(), @ViewChildren(), @ContentChild(), @ContentChildren(). In quell’articolo è stato spiegato che: i primi 2 ispezionano gli elementi che sono nel template HTML direttamente mentre i secondi 2 ispezionano gli elementi proiettati ovvero gli elementi presenti all’interno di &amp;lt; ng-content&amp;gt; &amp;lt; /ng-content&amp;gt;.&lt;/p&gt;

&lt;p&gt;Anche se abbiamo già avuto modo di intuire alcune cose, approfondiremo ora come utilizzare i decoratori @ContentChild(), @ContentChildren() per ritrovare referenze di componenti proiettati. Sotto possiamo vedere 3 componenti: PageComponent, TabsComponent, TabComponent.&lt;/p&gt;

&lt;h2&gt;
  
  
  PageComponent
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SpkI3bGD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bqwqu7qj5nsgrnv4jpee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SpkI3bGD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bqwqu7qj5nsgrnv4jpee.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TabsComponent
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jwHo0ZkA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c0gwlsoi7ia6ikmicetg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jwHo0ZkA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c0gwlsoi7ia6ikmicetg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TabComponent
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ybW5Tjgs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zdwvmkyokzwaxyuxg8au.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ybW5Tjgs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zdwvmkyokzwaxyuxg8au.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere all’interno del componente PageConponent è stato inserito un componente TabsComponent, ed all’interno del tag di apertura e chiusura sono stati inseriti 3 componenti TabComponent. Nel momento in cui eseguiamo il codice, l’output è quello dell’immagine sottostante.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fd5hAR6U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wzv2zysc7to78cnkhtnr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fd5hAR6U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wzv2zysc7to78cnkhtnr.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La posizione dell’output dei 3 componenti TabComponent (contenuti all’interno del tag di apertura e chiusura del componente TabsComponent) è determinata dai tag &amp;lt; ng-content&amp;gt; &amp;lt; /ng-content&amp;gt;. Nel nostro caso ne abbiamo 3 ed ognuno ha un attributo “select “ impostato sul valore di una classe CSS. In questo modo stabilisco nella posizione che voglio nel template HTML del componente TabsComponent, inoltre tra un &amp;lt; ng-content&amp;gt; &amp;lt; /ng-content&amp;gt; e l’altro può esserci altro testo (come nel nostro caso). Nel codice TypeScript dei primi 2 componenti possiamo notare altre cose interessati.&lt;/p&gt;

&lt;p&gt;Nel componente PageComponent troviamo i seguenti decoratori&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SZD_epNb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/egimk5hwe0g4pvwatlit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SZD_epNb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/egimk5hwe0g4pvwatlit.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In questo modo children1 e children2 contengono le referenze del componente TabsComponent e dei 3 componenti TabComponent. All’interno del componente PageComponent, non essendo ancora stati proiettati uso il decoratore @ViewChild.&lt;/p&gt;

&lt;p&gt;All’interno del componente TabsComponent, tanto per intenderci quello nel cui template HTML trovo i 3 &amp;lt; ng-content&amp;gt; &amp;lt; /ng-content&amp;gt;, i componenti TabComponent sono già stati proiettati. Per cui se voglio recuperare le loro referenze devo usare il decoratore.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mUTTYXo---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ytoqis9mxw4yg59ft2yq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mUTTYXo---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ytoqis9mxw4yg59ft2yq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una cosa che vale per tutti i decoratori ( @ViewChild(), @ViewChildren(), @ContentChild(), @ContentChildren() ), il valore recuperato è disponibile dopo l’evento ngAfterViewInit. Prima di tale evento le variabili potrebbero avere valore undefined se stiamo usando componenti dinamici. Con Angular 8 le cose cambiano leggermente, maggiori informazioni &lt;a href="https://angular.io/guide/static-query-migration"&gt;quì&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Con quest’articolo si completa il discorso sull’ “Angular Component Communication” ovvero sulla necessità che i componenti possano comunicare tra loro.&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://dev.to/mastefano64/introduzione-ad-angular-5ba7"&gt;Introduzione ad Angular / Sommario&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) &lt;a href="https://dev.to/mastefano64/angular-component-communication-data-binding-parte-1-321h"&gt;Angular Component Communication (Data Binding) – parte 1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) &lt;a href="https://dev.to/mastefano64/angular-component-communication-decoratori-input-output-parte-2-368f"&gt;Angular Component Communication (decoratori @Input, @Output) – parte 2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-template-reference-variable-e-i-decoratori-viewchild-viewchildren-contentchild-contentchildren-in-angular-2a7d"&gt;Cosa sono le Template Reference Variable e i decoratori @ViewChild @ViewChildren @ContentChild @ContentChildren in Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-projection-in-angular-ng-content-contentchild-contentchildren-aml"&gt;Cosa sono le “projection” in Angular (ng-content ContentChild ContentChildren)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6) &lt;a href="https://dev.to/mastefano64/come-manipolare-il-dom-da-un-applicazione-angular-2oj5"&gt;Come manipolare il DOM da un applicazione Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se volete contattarmi il mio profilo Linkedin è il seguente:&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/stefano-marchisio-sviluppatore-web-angular-javascript-aspnet-fullstack/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Cosa sono le Template Reference Variable e i decoratori @ViewChild @ViewChildren @ContentChild @ContentChildren in Angular</title>
      <dc:creator>Stefano Marchisio (sviluppatore freelance)</dc:creator>
      <pubDate>Tue, 02 Feb 2021 16:31:02 +0000</pubDate>
      <link>https://dev.to/mastefano64/cosa-sono-le-template-reference-variable-e-i-decoratori-viewchild-viewchildren-contentchild-contentchildren-in-angular-2a7d</link>
      <guid>https://dev.to/mastefano64/cosa-sono-le-template-reference-variable-e-i-decoratori-viewchild-viewchildren-contentchild-contentchildren-in-angular-2a7d</guid>
      <description>&lt;p&gt;&lt;a href="https://www.stefanomarchisio.it/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Quest'articolo mostra l'uso delle “Template Reference Variable” e come fare delle query DOM attraverso: @ViewChild @ViewChildren @ContentChild @ContentChildren per recuperare referenze
&lt;/h4&gt;

&lt;h2&gt;
  
  
  Template Reference Variable
&lt;/h2&gt;

&lt;p&gt;Una “Template Reference Variable” è una referenza ad un elemento all’interno in un template HTML, e con elemento si intende sia un semplice elemento HTML che un altro componente o direttiva presente nel template HTML. Nel primo caso avremo una referenza ad un elemento del DOM (ed il tipo associato è ElementRef) nel secondo caso una referenza ad un componente o direttiva. Le “Template Reference Variable” vengono anche usate per definire template con cui creare EmbeddedView o per identificare ViewContainer all’interno dei quali creare EmbeddedView. Una “Template Reference Variable” viene dichiarata mettendo il carattere “#” davanti al nome (come fosse un attributo addizionale).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1iiyms-H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pvnf86n066f3oaq4z3oz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1iiyms-H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pvnf86n066f3oaq4z3oz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nell'esempio sovrastante viene utilizzato un tag HTML, ma lo stesso discorso vale anche per un componente. Nel momento in cui dichiariamo una “TemplateReferenceVariable”, che per brevità in seguito chiameremo TRV, abbiamo accesso a tutte le proprietà e metodi definiti in quell’oggetto. Una “TRV” può essere utilizzata sia all’interno del templete HTML stesso ( per esempio in un espressione di binding "{  {  }  }" ) sia nel codice TypeScript di un componente. All’interno di un template HTML può anche essere passata come parametro ad un evento.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I5i2oJhv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/viw0jlg2zyzper6zekp8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I5i2oJhv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/viw0jlg2zyzper6zekp8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sopra si possono vedere 2 esempi: una TRV definita in un elemento HTML e una TRV definita in un component. Se viene dichiarata senza essere inizializzata conterrà una referenza all’elemento o componente. Esiste anche una seconda modalità per dichiararla (vedi sotto).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fxUx7FHa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e2fe6aqv15orci21wuyr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fxUx7FHa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e2fe6aqv15orci21wuyr.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In questo caso viene assegnato un valore alle TRV in fase di dichiarazione.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_1oYr9LT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sqeohr343tcajenlzxl5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_1oYr9LT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sqeohr343tcajenlzxl5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Per cui non conterrà più la referenza dell’elemento in cui è stata dichiarata, ma bensì conterrà l’oggetto che gli è stato assegnato (in questo caso la direttiva del FormModule). Nel caso di #f="ngForm", visto che la variabile viene passata ad un evento, nel codice TypeScript al metodo onSubmit(f) verrà passata la direttiva ngForm. Questo mi servirà per recuperare i valori dei campi del form.&lt;/p&gt;

&lt;p&gt;@ViewChild(), @ViewChildren(), @ContentChild(), @ContentChildren()&lt;/p&gt;

&lt;p&gt;All’interno del codice TypeScript di un componente una “TRV” dichiarata nel template HTML non è visibile ovvero se referenzio il suo nome nel codice otterrò un errore di compilazione. &lt;strong&gt;Ma Angular fornisce un meccanismo chiamato DOM query. Questa funzionalità permette di fare delle query all’interno del template HTML, per ottenere referenze a “Component”, “Directive” e “TRV” (definiti nel templete HTML).&lt;/strong&gt; Per far ciò devo usare i decoratori @ViewChild(), @ViewChildren(), @ContentChild(), @ContentChildren() nella dichiarazione di una variabile. &lt;/p&gt;

&lt;p&gt;I primi 2 decoratori: @ViewChild(), @ViewChildren() ispezionano gli elementi che sono nel template HTML direttamente.&lt;/p&gt;

&lt;p&gt;I secondi 2 decoratori: @ContentChild(), @ContentChildren() ispezionano gli elementi proiettati ovvero gli elementi presenti all’interno di &amp;lt; ng-content&amp;gt;&amp;lt; /ng-content&amp;gt; &lt;/p&gt;

&lt;p&gt;In entrambi i casi “Child” ritorna un solo elemento, mentre “Children” ritorna più elementi (nel caso la query trovi più elementi che soddisfano il criterio di ricerca).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Questi decoratori devono essere anteposti alla dichiarazione di una variabile&lt;/em&gt;, un po’ come avviene per i decoratori di @Input(), @Output(). &lt;em&gt;Sarà poi Angular che in modo automatico effettuera la DOM query e metterà il risultato nella variabile.&lt;/em&gt; L’unica cosa da tener presente è che il risultato potrebbe esserci solo dopo l’evento “ngAfterViewInit”. Prima di tale evento la variabile sarà undefined, se stiamo usando componenti dinamici. Con Angular 8 le cose cambiano leggermente, maggiori informazioni &lt;a href="https://angular.io/guide/static-query-migration"&gt;quì&lt;/a&gt;. Il tipo di dato contenuto in questa variabile dipenderà invece da cosa stiamo leggendo (ElementRef, TemplateRef, ViewContainerRef, ComponentCustom, DirectiveCustom, etc…)&lt;/p&gt;

&lt;p&gt;Fin qui abbiamo visto come recuperare un elemento facendo una DOM query con uno dei decoratori menzionati sopra: @ViewChild(), @ViewChildren(), @ContentChild(), @ContentChildren(). &lt;/p&gt;

&lt;p&gt;Ma esiste anche un’altra modalità! Ora, visto che tutti i componenti sono contenuti dentro un elemento custom del DOM e visto che tutte le direttive sono applicate ad elementi del DOM, componenti e direttive possono ottenere un istanza dell' ElementRef che li contiene tramite dependency injection.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Infatti dichiarando nel costruttore di un componente una variabile ElementRef, verrà passata tramite dependency injection la referenza dell’elemento che contiene il componente. Analogamente, dichiarando nel costruttore di una direttiva una variabile ElementRef, verrà passata tramite dependency injection la referenza dell’elemento a cui è applicata la direttiva.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;ElementRef: fornisce una referenza ad un elemento del DOM. Può essere iniettato nel costruttore di un componet / directive oppure letto tramite: @ViewChild(), @ViewChildren.&lt;/p&gt;

&lt;p&gt;TemplateRef: rappresenta il template con cui è possibile creare un EmbeddedView. Può essere iniettato nel costruttore (nel caso si tratti di una direttiva custum) oppure letto tramite: @ViewChild(), @ViewChildren().&lt;/p&gt;

&lt;p&gt;ViewContainerRef: rappresenta un contenitore o placeholder dove una o più viste possono essere attaccate. Può essere iniettato nel costruttore oppure letto tramite: @ViewChild(), @ViewChildren().&lt;/p&gt;

&lt;h2&gt;
  
  
  Sotto un primo esempio
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NAxZG1lR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l0ookrqo9wu5nvi9kk5n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NAxZG1lR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l0ookrqo9wu5nvi9kk5n.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In quest’esempio è stata attribuita una “TRV” ad un tag span. Nel codice TypeScript invece, tramite il decoratore @ViewChild leggiamo il valore di questa referenza e la mettiamo nella variabile “tref”. Tale valore sarà poi disponibile nell’evento ngAfterViewInit. &lt;/p&gt;

&lt;p&gt;La sintassi base per dichiarare un decoratore è la seguente. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7yHFExk3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jtod0c7yxk0311q426vu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7yHFExk3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jtod0c7yxk0311q426vu.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere è stato specificato “tref” come “template reference”. Il secondo parametro invece non è sempre obbligatorio, infatti Angular tenta di inferirlo da ciò che stiamo leggendo.&lt;/p&gt;

&lt;p&gt;Per cui il decoratore sopra avremmo potuto scriverlo nella forma abbreviata (essendo un semplice elemento HTML viene inferito come ElementRef).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y8QO8NAK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fz21f0sxa81emmhuyydh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y8QO8NAK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fz21f0sxa81emmhuyydh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anche nel caso si debba leggere una “TRV” associata ad un &amp;lt; ng-template&amp;gt; è possibile usare la forma abbreviata (essendo un ng-template viene inferito come TemplateRef). Ci sono dei casi però in cui Angular non riesce ad inferire il tipo, per cui è necessario usare la forma completa. Un tipico esempio è ViewContainerRef.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--65KD2PO5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8ceo9tzsciux22v4mfcn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--65KD2PO5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8ceo9tzsciux22v4mfcn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In quest’esempio leggiamo un template #tpl1 che viene usato per creare un EmbeddedView da inserire nel ViewContainer identifcato dalla #container1. Come si può vedere abbiamo usato la forma abbreviata per leggere il template, mentre abbiamo usato la forma completa per leggere il viewcontainer. Maggiori informazioni sulla manipolazione del DOM è possibile trovarle nei prossimi articoli.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sotto un secondo esempio
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qHwLwahZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5km2jsb535psa74banyc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qHwLwahZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5km2jsb535psa74banyc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In quest’esempio invece di definire e leggere una “TRV”, leggiamo la referenza di un componente definito nel template HTML. Nel decoratore non verrà passata una stringa con un nome, ma bensì verrà passato il componente. Stesso discorso nel caso volessimo leggere una direttiva custom o una direttiva build-in.&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://dev.to/mastefano64/introduzione-ad-angular-5ba7"&gt;Introduzione ad Angular / Sommario&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) &lt;a href="https://dev.to/mastefano64/angular-component-communication-data-binding-parte-1-321h"&gt;Angular Component Communication (Data Binding) – parte 1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) &lt;a href="https://dev.to/mastefano64/angular-component-communication-decoratori-input-output-parte-2-368f"&gt;Angular Component Communication (decoratori @Input, @Output) – parte 2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-template-reference-variable-e-i-decoratori-viewchild-viewchildren-contentchild-contentchildren-in-angular-2a7d"&gt;Cosa sono le Template Reference Variable e i decoratori @ViewChild @ViewChildren @ContentChild @ContentChildren in Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-projection-in-angular-ng-content-contentchild-contentchildren-aml"&gt;Cosa sono le “projection” in Angular (ng-content ContentChild ContentChildren)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6) &lt;a href="https://dev.to/mastefano64/come-manipolare-il-dom-da-un-applicazione-angular-2oj5"&gt;Come manipolare il DOM da un applicazione Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se volete contattarmi il mio profilo Linkedin è il seguente:&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/stefano-marchisio-sviluppatore-web-angular-javascript-aspnet-fullstack/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Angular Component Communication (decoratori @Input, @Output) – parte 2</title>
      <dc:creator>Stefano Marchisio (sviluppatore freelance)</dc:creator>
      <pubDate>Tue, 02 Feb 2021 16:07:57 +0000</pubDate>
      <link>https://dev.to/mastefano64/angular-component-communication-decoratori-input-output-parte-2-368f</link>
      <guid>https://dev.to/mastefano64/angular-component-communication-decoratori-input-output-parte-2-368f</guid>
      <description>&lt;p&gt;&lt;a href="https://www.stefanomarchisio.it/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Quest'articolo mostra l'uso dei decoratori di @Input, @Output per passare dati piuttosto che ricevere eventi.
&lt;/h4&gt;

&lt;p&gt;Nella prima parte di quest’articolo abbiamo introdotto il concetto di data binding e come può essere implementato in Angular: Iterpolation, Property binding, Event binding, TwoWay binding. In questa seconda parte continuiamo il discorso sul’ “Angular Component Communication” e parleremo dei decoratori di @Input, @Output.&lt;/p&gt;

&lt;p&gt;Angular à un framework a componenti, ed il template HTML di ogni componente può contenere al suo interno altri componenti in modo da formare una struttura ad albero. Detto questo nasce la necessità che i componenti siano in grado comunicare tra loro. In particolar modo che un componente padre possa inviare dati a componenti figlio, così come un componente figlio possa inviare dati al componente padre sotto forma di evento.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MZ4zKiib--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8wcv8n13wla5dcxu4f96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MZ4zKiib--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8wcv8n13wla5dcxu4f96.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questa funzionalità in Angular è fornita tramite decoratori di @Input(), @Output().&lt;/strong&gt; Un decoratore è una funzione preceduta dal carattere “@”, e deve essere posto in fase di dichiarazione prima di una variabile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0wyc17v4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u575n97hganqk6hk8p26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0wyc17v4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u575n97hganqk6hk8p26.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sopra si può vedere un esempio di dichiarazione di un parametro di Input. Nella dichiarazione del parametro di Output assegniamo alla variabile l’oggetto “EventEmitter” (che può essere tipizzato). L’oggetto “EventEmitter” è un Observable e possiede un metodo “emit()”, questo metodo viene invocato quando vogliamo lanciare l’evento. Sotto possiamo vedere un esempio completo di 2 componenti: padre e figlio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_PdPiffO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6p11hi16r82cdeezz88g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_PdPiffO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6p11hi16r82cdeezz88g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Parent Component
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v4zQptci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1ia6ufgj3iv6n690ij6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v4zQptci--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1ia6ufgj3iv6n690ij6q.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Child Component
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0ua3oDQ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/99wfk2l5au3xgeautsmj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0ua3oDQ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/99wfk2l5au3xgeautsmj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere, nel template HTML del “Parent component” è stato dichiarato il “Child Component” , ed il tag  ha una proprietà di binding “data” che rappresenta il parametro che vogliamo passare. All’interno del “Child Component” è stata poi dichiarata una variabile preceduta dal decoratore @Input(), questo fa si che Angular metta in questa variabile ciò che era presente nella proprietà di binding “data” del “Parent component”.&lt;/p&gt;

&lt;p&gt;Per quanto riguarda i parametri di Output, nel “Child Component” è stata dichiarata una variabile preceduta dal decoratore @Output(). Nel momento in cui vogliamo sollevare l’evento basta richiamare il metodo “emit()” passando come parametro l’argomento che vogliamo ritornare. All’interno del “Parent component” devo infine dichiarare un event-handler che riceva tale evento.&lt;/p&gt;

&lt;p&gt;I parametri di Input sono disponibili solo dopo l’evento ngOnInit e vengono aggiornati nel caso di modifiche. Nel nostro esempio troviamo un solo parametro di input, ma in un componente possono essere presenti n. parametri di Input. Come detto all’inizio Angular è un framework a componenti ed ogni componente ha un proprio “lifecycle” scandito da eventi che è possibile intercettare. Tra questi ngOnChanges(changes: SimpleChanges) notifica quando un parametro di Input viene modificato. Come si può vedere quest’evento ha un argomento “SimpleChanges” che contiene i parametri di Input modificati ed i relativi valori (correnti e vecchi).&lt;/p&gt;

&lt;p&gt;Con la sintassi base per la dichiarazione di un parametro di Input ovvero quella che antepone il decoratore @Input() davanti al nome di una variabile, posso lanciare un operazione su dati solo nell’evento ngOnInit. Ora, visto che l’evento ngOnInit viene eseguito una sola volta all’atto della creazione di un componente, in seguito se un parametro di Input cambia non siamo in grado di rilanciare un operazione sui dati. L’evento ngOnChanges(changes: SimpleChanges) può risultare utile in un contesto simile, perché notifica tutte le volte che un parametro di Input viene modificato, permettendoci di rilanciare eventuali operazioni sui dati.&lt;/p&gt;

&lt;p&gt;Nel caso abbiamo la necessità di rilanciare un operazione sui dati tutte le volte che un parametro di Input viene modificato, ma non vogliamo utilizzare l’evento ngOnChanges(changes: SimpleChanges), abbiamo un’altra possibilità. Dichiarare il parametro di Input con getter e setter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F3BVFwnC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8x9mbx2luikixg43svaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F3BVFwnC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8x9mbx2luikixg43svaj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In questo modo quando il parametro di Input viene modificato, viene automaticamente invocato il metodo this.updatePeriodTypes().&lt;/p&gt;

&lt;p&gt;Una cosa importante che dobbiamo tenere in considerazione è questa. Abbiamo detto che Angular notifica tramite l’evento ngOnChanges(changes: SimpleChanges) quando un parametro di Input viene modificato. Senza entrare troppo nel dettaglio, questo avviene confrontando i vecchi valori con i nuovi, e nel caso risultano diversi scatta la notifica. Per questo motivo dobbiamo tenere in considerazione se stiamo operando con tipi valore o tipi referenza (un’oggetto). Se stiamo lavorando con un oggetto e modifichiamo il valore di una sua proprietà, Angular non si accorge della modifica perché la referenza non è cambiata, per questo motivo l’evento ngOnChanges(changes: SimpleChanges) non scatterà.&lt;/p&gt;

&lt;p&gt;A questo punto potremmo continuare il discorso parlando di “Immutabilità degli oggetti” e di “OnPush Change Detection Strategy” ma non fa parte di quest’articolo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subject
&lt;/h2&gt;

&lt;p&gt;Una delle regole fondamentali quando si parla di architetture software è che ci sia un debole accoppiamento tra le parti, ovvero che non ci creino situazioni in cui una parte dipende dall’altra a causa ad una referenza tipizzata. Con i decoratori di @Input / @Output possiamo mettere in comunicazione 2 componenti nel caso ci sia una relazione padre e figlio, senza incorrere in questo tipo di problemi. Nel caso invece tra 2 o più componenti non ci sia una relazione padre e figlio dobbiamo usare altre tecniche per raggiungere lo scopo. In Angular ci viene in aiuto il Subject che è un tipo speciale di Observable (infatti un Subject è al tempo stesso Observer e Observable). Per cui se creiamo un servizio singleton che incapsuli un Subject, permettiamo a n. componenti di registrarsi e rimanere in attesa di notifiche, che possono provenire da altri componenti. In questo modo l’unica dipendenza che ha un componente è quella del servizio. Sotto un esempio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JizEqbFN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/svwzz1fyp9ym00veyuvg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JizEqbFN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/svwzz1fyp9ym00veyuvg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://dev.to/mastefano64/introduzione-ad-angular-5ba7"&gt;Introduzione ad Angular / Sommario&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) &lt;a href="https://dev.to/mastefano64/angular-component-communication-data-binding-parte-1-321h"&gt;Angular Component Communication (Data Binding) – parte 1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) &lt;a href="https://dev.to/mastefano64/angular-component-communication-decoratori-input-output-parte-2-368f"&gt;Angular Component Communication (decoratori @Input, @Output) – parte 2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-template-reference-variable-e-i-decoratori-viewchild-viewchildren-contentchild-contentchildren-in-angular-2a7d"&gt;Cosa sono le Template Reference Variable e i decoratori @ViewChild @ViewChildren @ContentChild @ContentChildren in Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5) &lt;a href="https://dev.to/mastefano64/cosa-sono-le-projection-in-angular-ng-content-contentchild-contentchildren-aml"&gt;Cosa sono le “projection” in Angular (ng-content ContentChild ContentChildren)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6) &lt;a href="https://dev.to/mastefano64/come-manipolare-il-dom-da-un-applicazione-angular-2oj5"&gt;Come manipolare il DOM da un applicazione Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se volete contattarmi il mio profilo Linkedin è il seguente:&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/stefano-marchisio-sviluppatore-web-angular-javascript-aspnet-fullstack/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Eseguire e debuggare un'​ applicazione ASP.NET Core in Visual Studio utilizzando WSL (windows subsystem for linux)</title>
      <dc:creator>Stefano Marchisio (sviluppatore freelance)</dc:creator>
      <pubDate>Sat, 30 Jan 2021 11:19:55 +0000</pubDate>
      <link>https://dev.to/mastefano64/eseguire-e-debuggare-un-applicazione-asp-net-core-in-visual-studio-utilizzando-wsl-windows-subsystem-for-linux-20om</link>
      <guid>https://dev.to/mastefano64/eseguire-e-debuggare-un-applicazione-asp-net-core-in-visual-studio-utilizzando-wsl-windows-subsystem-for-linux-20om</guid>
      <description>&lt;p&gt;&lt;a href="https://www.stefanomarchisio.it/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduzione
&lt;/h2&gt;

&lt;p&gt;Il “sottosistema Windows per Linux” (o wsl) consente agli sviluppatori di eseguire un ambiente Linux all’interno di Windows, questo ambiente include la maggior parte delle applicazioni e degli strumenti da riga di comando presenti in Linux, il tutto senza il sovraccarico di una macchina virtuale tradizionale o di una configurazione di doppio avvio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MyK-XDqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vc9ykc8j9w9mz446k7dw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MyK-XDqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vc9ykc8j9w9mz446k7dw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ciò risulterà utile (non in produzione) nel momento in cui vogliamo effettuare il debug di un applicazione ASP.NET Core in ambiente Linux. Seppur con ASP.NET Core sia possibile creare applicazioni multipiattaforma (Windows, Linux, Mec), se un’applicazione è stata sviluppata in ambiente Windows quando viene pubblicata in ambiente Linux possono sorgere dei problemi (per esempio a causa di come sono scritti i percorsi dei file). In questo modo sarà possibile lanciare l’applicazione ed effettuare il debug all’interno di Visual Studio (nelle cartelle di progetto in Windows), utilizzando un runtime di una macchina Linux a tutti gli effetti, per riscontrare e correggere eventuali problemi.&lt;/p&gt;

&lt;p&gt;Esistono 2 versioni di WSL (windows subsystem for linux), più precisamente WSL1 e WSL2. In WSL1 non è presente un kernel linux, l’applicazione viene eseguita tramite una traslazione tra la “distribuzione linux” ed il “kernel windows”. Con l’avvento di WSL2 Microsoft abbandona l'emulazione delle API e integra una copia dell'interno kernel Linux all’interno di Windows. Il kernel è stato prelevato dal sito ufficiale (kernel.org), ottimizzato allo scopo e ricompilato; viene poi eseguito all'interno di una macchina virtuale light invisibile all'utente.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Windows subsystem for linux è presente di default in Windows 10 (anche se non attivato), in quest’articolo vedremo come attivarlo e come scaricare una distribuzione Linux dallo store di Windows 10. Una volta che avremo poi un sottosistema Linux funzionante, vedremo come fare il deploy di un applicazione ASP.NET Core e come fare l’ ”attach” del “debugger” per poterla debuggare.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Attivazione del Windows subsystem for linux
&lt;/h2&gt;

&lt;p&gt;Per prima cosa dobbiamo andare attraverso il pannello di controllo in istallazione programmi e cliccare su “Turn windows features on or off”. A questo punto verrà visualizzato un popup con le varie features che possono essere attivate, se non sono già state selezionate dobbiamo selezionare: “Virtual Machine Platform” e “Windows Subsystem for Linux”. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hUo9mGvp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/no6d6ga3a5qmitxrlr2k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hUo9mGvp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/no6d6ga3a5qmitxrlr2k.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dopo aver riavviato il pc Windows avrà installato ciò che ci serve, o meglio avrà predisposto la macchina installando il Kernel Linux anche se non sarà ancora presente una distribuzione Linux reale. Per installare una distribuzione Linux reale dobbiamo invece andare sul Windows Store e scegliere la distribuzione che desideriamo installare tra quelle disponibili.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installazione di una distribuzione Linux
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5vC47GH2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tf0y7guiz88ttq9ivdl9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5vC47GH2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tf0y7guiz88ttq9ivdl9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4cypoebI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/49eeug23ino3q0qds8u6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4cypoebI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/49eeug23ino3q0qds8u6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dopo che Windows ha finito di scaricare la distribuzione selezionata dobbiamo lanciarla come si farebbe con qualsiasi altra applicazione. La prima volta si aprirà una finestra console e verrà chiesto di attendere uno o due minuti affinché i file vengano decompressi e archiviati sul pc (i lanci futuri dovrebbero richiedere meno di un secondo), verrà inoltre chiesto di inserire uno “username” ed una “password”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--igTExbh8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e4uklp9aczomd8i2n14z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--igTExbh8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e4uklp9aczomd8i2n14z.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A questo punto la distribuzione Linux da noi scelta è stata installata sul pc. Infatti se apriamo il menu start di Windows la vedremo insieme agli altri programmi, analogamente se clicchiamo si aprirà una finestra console con un terminale Linux. Importante, potrebbe comparire la scritta “Access is denied”, per ovviare a questo problema dobbiamo lanciare la console come amministratore.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jZFY_lpd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g1xe5xk7z1a4bi1y1frm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jZFY_lpd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g1xe5xk7z1a4bi1y1frm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k7qx-L91--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o7f5kj1dc1i2w072j26u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k7qx-L91--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o7f5kj1dc1i2w072j26u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere dall’immagine sovrastante una volta entrati nel sottosistema Linux ci troviamo nella directory di lavoro assegnata al nostro utente, sarà quindi possibile eseguire qualsiasi comando Linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conosciamo il commando WSL.EXE
&lt;/h2&gt;

&lt;p&gt;Nel momento in cui è stato attivato/installato “windows subsystem for linux” è stato aggiunto al prompt dei comandi un nuovo comando: wsl.exe. Questo comando ci permette di gestire le varie distribuzioni Linux presenti sulla nostra macchina ed in particolar modo di: 1) visualizzare le distribuzioni linux installate (può essere presente anche più di una distribuzione). 2) Lanciare una distribuzione. 3) Impostare wsl1 o wsl2 come formato predefinito quando si installa una nuova distribuzione 4) Convertire una distribuzione da un formato all’altro: wsl1 =&amp;gt; wsl2 o wsl2 =&amp;gt; wsl1 5) Molto altro ancora &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--57GcciIT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/udk15bbkjgqhtmcihbxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--57GcciIT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/udk15bbkjgqhtmcihbxq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere dall’immagine sovrastante sul sistema era già presente la distribuzione 20.04 di Ubuntu, nell’esempio abbiamo voluto installare anche la distribuzione 18.04 di Ubuntu. Come si può vedere la distribuzione appena installata utilizza il formato wsl1, pertanto dobbiamo convertirla al formato wsl2. Questo può essere fatto attraverso il comando “wsl –set-default Ubuntu-18.04 2”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---lg6tzTd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u44eau1xwu9h31ldj900.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---lg6tzTd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u44eau1xwu9h31ldj900.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adesso entrambe le distribuzioni utilizzano il formato wsl2. E’ possibile lanciare una distribuzione oltre che dal menu start di Windows anche attraverso il comando wsl, infatti i se digitiamo il comando “wsl -d Ubuntu-18.04” verrà aperta un finestra di terminale con la distribuzione desiderata. Per verificare che la versione sia quella corretta possiamo digitare il comando “lsb_release -a”. Maggiari informazioni sul comando wsl le potete trovare nella guida in linea di wsl.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interoperabilità tra il file system di Windows e quello di Linux
&lt;/h2&gt;

&lt;p&gt;Giunti a questo punto ci ritroviamo più sistemi operativi affiancati, in particolar modo abbiamo Windows che funge da host e una o più distribuzioni Linux che girano su macchine virtuali light. Per rendere più agevole il lavoro dello sviluppatore, da ognuno dei sistemi operativi è possibile accedere agevolmente al file system degli altri sistemi operativi.&lt;/p&gt;

&lt;p&gt;1) Dall’interno di Windows è possibile accedere al file system delle varie distribuzioni Linux attraverso la risorsa di rete \wsl$.&lt;/p&gt;

&lt;p&gt;2) Analogamente ogni distribuzione Linux monta il file system della macchina Windows sul seguente percorso “/mnt/”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fz8mW_pU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cb1jyp26x75dvp1dzwd8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fz8mW_pU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cb1jyp26x75dvp1dzwd8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--idwyc0-I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vmbfam1d868vb2ounexo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--idwyc0-I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vmbfam1d868vb2ounexo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V_ckAXQl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l2lj0rq88wmhjqnxhbta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V_ckAXQl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l2lj0rq88wmhjqnxhbta.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In questo modo, in seguito sarà facilmente possibile posizionarsi nella directory di lavoro di un progetto Visual Studio (in Windows) dall’interno di un ambiente Linux, per poter poi lanciare la soluzione o avviare il debug in ambiente Linux.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Come mostra l’immagine sovrastante, dall’interno di un ambiante Linux ci siamo posizionati in un progetto Visual Studio (in Windows) contenuto nel drive “Z”.&lt;/p&gt;

&lt;p&gt;Dall’interno di un ambiente Linux è anche possibile digitando il comando “explorer.exe .” aprire esplora risorse in Windows, mostrando il contenuto di una directory dell’ambiente Linux. Infatti l’interprete dei comandi Linux, prova a lanciare in Windows ogni file che ha come suffisso “.exe”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FLJGdgBJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/60qi1ml7hchc5sxfebu3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FLJGdgBJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/60qi1ml7hchc5sxfebu3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Perché usare Sottosistema Windows per Linux anziché Linux in una macchina virtuale?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sottosistema Windows per Linux richiede un minor numero di risorse (CPU, memoria e file system) rispetto a una macchina virtuale completa. Consente di eseguire applicazioni e strumenti da riga di comando di Linux insieme alle applicazioni desktop Windows e di accedere ai rispettivi file system.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;NOTA IMPORTANTE: una delle principali limitazioni di Sottosistema Windows per Linux è la mancanza di supporto per la modifica diretta di file nel file system delle distribuzioni Linux tramite applicazioni o strumenti di Windows. Vedi: &lt;a href="https://devblogs.microsoft.com/commandline/do-not-change-linux-files-using-windows-apps-and-tools/"&gt;Do not change Linux files using Windows apps and tools&lt;/a&gt; (non modificare i file linux usando app e strumenti di windows).&lt;/p&gt;

&lt;h2&gt;
  
  
  Spostiamo la distribuzione appena installata in un'altra cartella
&lt;/h2&gt;

&lt;p&gt;Di default le varie distribuzioni linux installate vengono messe all’interno di “C:”, questo può essere un problema se abbiamo un SSD con poco spazio, per questo motivo dobbiamo trovare un modo per poterle spostare in altra unita. &lt;/p&gt;

&lt;p&gt;Questo può essere fatto tramite utility “LxRunOffline” che viene lanciata all’interno della power shell di Windows. Per installare “LxRunOffline” dobbiamo aver prima installato il package manager “Chocolate”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MkjxBuIf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/foac7q0ai4dyc1yd29ol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MkjxBuIf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/foac7q0ai4dyc1yd29ol.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere dall’immagine sovrastante la distribuzione verrà spostata nella cartella: “Z:\zzz-linux\Ubuntu-18.04”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installiamo l’SDK o il RUNTIME di ASP.NET Core nella distribuzione Linux
&lt;/h2&gt;

&lt;p&gt;Prima di continuare di continuare dobbiamo però installare l’SDK o il RUNTIME di ASP.NET Core nella distribuzione Linux. Per far ciò si utilizzano i package manager presenti in Linux.&lt;/p&gt;

&lt;p&gt;L'installazione con APT può essere fatta con pochi comandi, però prima di installare dotnet si devono eseguire i seguenti comandi per aggiungere la chiave di firma del pacchetto Microsoft all'elenco di chiavi attendibili e aggiungere il repository del pacchetto. Aprire quindi un terminale Linux e digitare.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;wget &lt;a href="https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb"&gt;https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb&lt;/a&gt; -O packages-microsoft-prod.deb&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;sudo dpkg -i packages-microsoft-prod.deb&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A questo punto è possibile installare dotnet scegliendo se installare anche SDK o solo il RUNTIME, nel caso si decide di installare l’SDK non è più necessario installare il RUNTIME.&lt;/p&gt;

&lt;p&gt;sudo apt-get update; \ &lt;/p&gt;

&lt;p&gt;sudo apt-get install -y apt-transport-https &amp;amp;&amp;amp; \ &lt;/p&gt;

&lt;p&gt;sudo apt-get update &amp;amp;&amp;amp; \ &lt;/p&gt;

&lt;p&gt;sudo apt-get install -y dotnet-sdk-5.0 &lt;/p&gt;

&lt;p&gt;oppure&lt;/p&gt;

&lt;p&gt;sudo apt-get update; \ &lt;/p&gt;

&lt;p&gt;sudo apt-get install -y apt-transport-https &amp;amp;&amp;amp; \ &lt;/p&gt;

&lt;p&gt;sudo apt-get update &amp;amp;&amp;amp; \ &lt;/p&gt;

&lt;p&gt;sudo apt-get install -y aspnetcore-runtime-5.0&lt;/p&gt;

&lt;p&gt;Maggiori informazioni è possibile trovarle &lt;a href="https://docs.microsoft.com/it-it/dotnet/core/install/linux-ubuntu"&gt;qui&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Una volta che abbiamo installato SDK o il RUNTIME possiamo provare ad eseguire la nostra applicazione all’interno dell’ambiente Linux, ma per far ciò dobbiamo prima fare il deploy all’interno di un folder di prova. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hxz4rgvb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/za9oe6q6lzrj1lhjo9yt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hxz4rgvb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/za9oe6q6lzrj1lhjo9yt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La directory dove è stata pubblicata l’applicazione è la seguente.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Z:\zzz-linux\Projects\WebApplication1\WebApplication1\bin\Debug\net5.0\publish&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apriamo ora un terminale Linux e tramite il comando “cd” ed entriamo nella directory dove è stata pubblicata l’applicazione.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;cd /mnt/z/zzz-linux/Projects/WebApplication1/WebApplication1/bin/Debug/net5.0/publish&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A questo punto possiamo lanciare l’applicazione tramite il commando “dotnet”.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;dotnet WebApplication1.dll&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EHdnVo8e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jmhbux8v92g6pkqbb9mw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EHdnVo8e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jmhbux8v92g6pkqbb9mw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere dall’immagine sovrastante il server “Kestrel” è partito e ci segnala che l’applicazione è ora visibile ai seguenti indirizzi: “&lt;a href="http://localhost:5000%E2%80%9D"&gt;http://localhost:5000”&lt;/a&gt; e “&lt;a href="https://localhost:5001%E2%80%9D"&gt;https://localhost:5001”&lt;/a&gt; (da tener presente che la console è in ambiente Linux). Se ora apriamo il browser all’interno di Windows ed inseriamo uno dei 2 indirizzi, vedremo la nostra applicazione. &lt;/p&gt;

&lt;h2&gt;
  
  
  Abilitiamo il protocollo SSH ed installiamo il debugger remoto di dotnet
&lt;/h2&gt;

&lt;p&gt;Fino ad ora ci siamo limitati a lanciare un applicazione in ambiente Linux da un browser in Windows. Ma prima di poter effettuare il debug dobbiamo fare ancora un paio di cose.&lt;/p&gt;

&lt;p&gt;Essendo Visual Studio e l’ambiente Linux che esegue l’applicazione su 2 sistemi operativi diversi, siamo obbligati a lanciare una sessione di debug remoto. Per questo motivo dobbiamo abilitare protocollo SSH e poi installare il debugger remoto di dotnet all’interno di Linux. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nTS5hbqN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1u8c7mx1oa17dxshnps6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nTS5hbqN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1u8c7mx1oa17dxshnps6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I default è presente un server SSH all’interno della distribuzione Linux, ma a volte capita che nel momento in cui viene lanciato solleva un errore. Per questo motivo è bene disinstallarlo per poi installarlo nuovamente.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;sudo apt-get remove openssh-server&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;sudo apt-get install openssh-server&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Una volta reinstallato il server SSH dobbiamo andare a impostare i parametri di configurazione “PasswordAuthentication yes” e “AllowUsers ” contenuti nel file “/etc/ssh/sshd_config”. Infatti di default la password authentication è disabilitata e non sono presenti utenti nella lista degli utenti abilitati. Per editare il file “/etc/ssh/sshd_config” possiamo se non ancora presente installare “nano”, un semplice e funzionale editor di testo.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;sudo apt-get install nano&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;sudo nano /etc/ssh/sshd_config&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PasswordAuthentication yes&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AllowUsers &lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Una volta terminata la configurazione del servizio SSH riavviamo il server.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;sudo service ssh --full-restart&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Installiamo ora l’ unzip e il debug di dotnet.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;sudo apt-get install unzip&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;curl -sSL &lt;a href="https://aka.ms/getvsdbgsh"&gt;https://aka.ms/getvsdbgsh&lt;/a&gt; | bash /dev/stdin -v latest -l ~/vsdbg&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Tramite “curl” scarichiamo lo script “getvsdbgsh” che una volta lanciato provvederà a completare l’istallazione e la configurazione del debugger.&lt;/p&gt;

&lt;p&gt;Se tutto à andato per il verso giusto, siamo ora in grado di lanciare da Visual Studio una sessione di debug di un applicazione che viene eseguita in ambiente Linux. Prima di lanciare la sessione di debug recuperiamo però l’indirizzo ip dell’ambiente Linux.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AYxS_JMG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o9fbduqzfci6klotg1q8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AYxS_JMG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o9fbduqzfci6klotg1q8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MIB4Fvjn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8ibzn7mbi4niyll8en0s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MIB4Fvjn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8ibzn7mbi4niyll8en0s.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lfjNtdIj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sre1352zjza5aaake5n0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lfjNtdIj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sre1352zjza5aaake5n0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q-VRIXOC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iwyj8auw759jj0wmnbwt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q-VRIXOC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iwyj8auw759jj0wmnbwt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nel momento in cui clicchiamo su “OK” partirà il debug di Visual Studio, se inseriamo un break-point sul metodo “Index” nel momento in cui effettuiamo il refresh della pagina il debug si arresterà al punto selezionato.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KmQ4-pAu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lyjl9lgksjfqt2dro4up.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KmQ4-pAu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lyjl9lgksjfqt2dro4up.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusioni
&lt;/h2&gt;

&lt;p&gt;Giunti a questo punto abbiamo visto come è possibile lanciare una sessione di debug da Visual Studio di un applicazione eseguita in un ambiente Linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10"&gt;Windows Subsystem for Linux Installation Guide for Windows 10&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/core/install/linux"&gt;Install .NET on Linux&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu"&gt;Install the .NET SDK or the .NET Runtime on Ubuntu&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/devops/debugging-net-core-on-unix-over-ssh/"&gt;Debugging .NET Core on Unix over SSH&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/kapilgorve/move-install-wsl-distro-from-c-drive-to-another-drive-19g9"&gt;Move/Install WSl distro from C drive to another drive&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se volete contattarmi il mio profilo Linkedin è il seguente:&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/stefano-marchisio-sviluppatore-web-angular-javascript-aspnet-fullstack/"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aspnet</category>
      <category>windows</category>
      <category>linux</category>
      <category>visualstudio</category>
    </item>
    <item>
      <title>Differenze tra providers vs viewProviders in Angular (e tree shaking)</title>
      <dc:creator>Stefano Marchisio (sviluppatore freelance)</dc:creator>
      <pubDate>Sun, 29 Nov 2020 15:38:45 +0000</pubDate>
      <link>https://dev.to/mastefano64/differenze-tra-providers-e-viewproviders-in-angular-e-tree-shaking-2ap4</link>
      <guid>https://dev.to/mastefano64/differenze-tra-providers-e-viewproviders-in-angular-e-tree-shaking-2ap4</guid>
      <description>&lt;h2&gt;
  
  
  Come modificare il meccanismo di dependency injection presente in Angular.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.stefanomarchisio.it" rel="noopener noreferrer"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduzione
&lt;/h3&gt;

&lt;p&gt;L’obiettivo del presente articolo e spiegare la differenza tra &lt;em&gt;l’injectors “providers”&lt;/em&gt; e &lt;em&gt;l’injectors “viewProviders”&lt;/em&gt;. Anche se non è trattato pienamente nel presente articolo, facciamo prima un piccolo recall del meccanismo di dependency injection presente in Angular.&lt;/p&gt;

&lt;p&gt;In Angular (come in altri framework) è presente una funzionalità per creare e iniettare un oggetto nel costruttore di una classe. L’oggetto iniettato potrà poi essere di 2 tipi: 1) Singleton ovvero verrà creata &lt;strong&gt;un'unica istanza&lt;/strong&gt; condivisa che verrà iniettata tutte le volte che viene richiesta 2) Verrà iniettata &lt;strong&gt;una nuova istanza&lt;/strong&gt; tutte le volte che viene richiesta.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Decidere di attivare una modalità piuttosto che l’altra dipende dove viene registrato il servizio!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;1) Se un servizio viene registrato all’interno di un modulo tramite l’array providers avremo un servizio singleton (dalla versione di Angula 6 abbiamo anche l’attributo providedIn del decoratore @Injectable, vedi sotto). &lt;/p&gt;

&lt;p&gt;2) Se un servizio viene registrato all’interno di un componente tramite  l’array providers avremo un nuovo servizio che verrà creato tutte le volte che un componente viene istanziato, tale servizio sarà poi visibile sia dal componente che lo ha registrato e sia dagli eventuali figli presenti nel componente che ne fanno richiesta. &lt;/p&gt;

&lt;p&gt;Entrando nel dettaglio, quando all’interno del costruttore di un componente viene richiesto un servizio, il motore di dependency injection presente in Angular per prima cosa guarda se nel componente è stato registrato un servizio, in caso contrario risale l’albero dei componenti per guardare nei componenti di livello superiore, se giunto al nodo radice non ha trovato niente guarda allora nel modulo. Ciò implica che in Angular esistono 2 tipi di injector: root-injector e child-injector.&lt;/p&gt;

&lt;p&gt;Fin qui nulla di strano, e per maggiori informazioni sulla dependency injection si rimanda alla &lt;a href="https://angular.io/guide/dependency-injection" rel="noopener noreferrer"&gt;documentazione ufficiale&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Arriviamo ora allo scopo del presente articolo, la cosa che forse molti non conoscono è che &lt;strong&gt;all’interno di un componente&lt;/strong&gt; è possibile registrare un servizio oltre che con l’array “providers” anche con l’array “viewProviders”. Infatti nel decoratore “@Component” usato per definire un componente, oltre alle proprietà base: selector, templateUrl, styleUrls; troviamo  le proprietà: providers e viewProviders (che servono appunto per registrare un servizio).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Non si riscontrano differenze tra “providers” e “viewProviders” finchè all’interno del template HTML non è presente un tag &amp;lt;ng-content&amp;gt;; ovvero esiste del contenuto proiettato. Ciò vuol dire che in un componente “Padre” i figli vengono iniettati nel seguente modo: &amp;lt;parent&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parent&amp;gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In questo caso (se esiste del contenuto proiettato) se un componente “child” richiede un servizio (che è registrato nel “parent”) il motore di dependency injection presente in Angular NON fornirà il servizio come avverrebbe di default, ma va subito in cima al component tree. Questo avviene per prevenire che librerie di 3 parti possano usare dei nostri servizi. Vediamo ora 3 brevi esempi.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdpgsso1rdrkhhhmc67n5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdpgsso1rdrkhhhmc67n5.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmk1i8w08nsqfme3shakc.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmk1i8w08nsqfme3shakc.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I 2 templete HTML sovrastanti sono utilizzati nell’esempio 1 e nell’esempio 2. Come si può vedere vengono definiti 2 componenti “parent” affiancati, all’interno di ogni componente parent è poi presente un componte “child”.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Il servizio è registrato solo all’interno del modulo
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fprry5elem7b1spyjdssd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fprry5elem7b1spyjdssd.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fallsxpauokvpg5219xsq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fallsxpauokvpg5219xsq.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In questo primo esempio sono presenti 2 componenti “parent” affiancati, sia il componente “parent” che il componente “child” (definito all’interno del componente parent) richiedono lo stesso servizio. Essendo il servizio registrato nel modulo otterranno tutti la stessa istanza (parent e child). Per questo motivo qualsiasi cosa che venga digitata in una delle 2 textbox del componente “parent” verrà replicata anche nell’altra textbox, così come nella lables dei controlli “child”.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Il servizio è registrato all’interno del componente parent tramite “providers”
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi4k1usd1dhgdw7y7orgd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi4k1usd1dhgdw7y7orgd.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbkgsmmi5yhrtsbqvtgo4.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbkgsmmi5yhrtsbqvtgo4.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In questo secondo esempio sono presenti 2 componenti “parent” affiancati, sia il componente “parent” che il componente “child” (definito all’interno del componente parent) richiedono lo stesso servizio. Essendo il servizio registrato nel componente “parent” verranno create 2 istanze diverse per ciascun componente, i componenti “child” otterranno poi l’istanza del componente “parent” corrispondente. Per questo motivo le 2 textbox saranno disgiunte, quello che viene digitato in una textbox non verrà replicato anche nell’altra textbox, verrà solo replicato nel componente “child” corrispondente.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Il servizio è registrato all’interno del componente parent tramite “viewProviders”
&lt;/h3&gt;

&lt;p&gt;Quello visto fino ad ora è il funzionamento standard del motore di dependency injection presente in Angular. Vedremo ora che in presenza di contenuto proiettato, se un servizio è registrato tramite “viewProviders”, le cose cambiano.&lt;/p&gt;

&lt;p&gt;Sotto si può vedere il template HTML del componente contenitore&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs9amock5lue7w3831vgq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs9amock5lue7w3831vgq.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sotto si può vedere il template HTML del componente “parent”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff6xem9z9wkd8073j3j3a.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff6xem9z9wkd8073j3j3a.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqyubuaeuqhcmy29kkern.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqyubuaeuqhcmy29kkern.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come si può vedere nei template HTML sovrastanti all’interno del componente contenitore sono presenti 2 componenti “parent” affiancati: &amp;lt;parentc&amp;gt;&amp;lt;child&amp;gt;&amp;lt;/child&amp;gt;&amp;lt;/parentc&amp;gt;. Il componente “child” in questo caso viene proiettato a differenza dei 2 esempi precedenti in cui era dichiarato nel componente “parent” corrispondente.  Nel componente “parent” troviamo solo il tag &amp;lt;ng-content&amp;gt;. &lt;strong&gt;Cosa importante, nel componente “parent” il servizio è registrato attaverso “viewProviders”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc9g4htue0lzx7lzp6zu4.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc9g4htue0lzx7lzp6zu4.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6qu8f3xqcq6jb01fef6k.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6qu8f3xqcq6jb01fef6k.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In questo terzo esempio sono presenti 2 componenti “parent” affiancati, sia il componente “parent” che il componente “child” richiedono lo stesso servizio, in questo caso però il componente “child” viene proiettato. Essendo il servizio registrato nel componente “parent” verranno create 2 istanze diverse per ciascun componente. Per questo motivo le 2 textbox saranno disgiunte, quello che viene digitato in una textbox non verrà replicato anche nell’altra textbox. A differenza degli altri 2 esempi, ciò che viene digitato in una textbox NON verrà replicato nel componente “child” corrispondente, questo perché il componente “child” non otterrà l’istanza del servizio dal componente “parent” perché registrato con “viewProviders”. Questo avviene per prevenire che librerie di 3 parti possano usare dei nostri servizi. &lt;/p&gt;

&lt;h3&gt;
  
  
  Servizi tree-shakable
&lt;/h3&gt;

&lt;p&gt;Il tree shaking è l’operazione che implica la rimozione del codice non utilizzato all'interno di un'applicazione Angular in modo che non sia presente nel bundle filale.&lt;/p&gt;

&lt;p&gt;Con &lt;a href="https://www.linkedin.com/pulse/cos%C3%A8-ivy-e-perch%C3%A9-%C3%A8-stato-introdotto-stefano-marchisio" rel="noopener noreferrer"&gt;Angular Ivy&lt;/a&gt; il nuovo set di istruzioni è stato progettato per raggiungere gli obiettivi sopra menzionati. Infatti è stato progettato per essere completamente tree-shakeable. Ciò significa che se non viene utilizzata una particolare funzione di Angular, le istruzioni corrispondenti a quella funzione non saranno inserite nel bundle finale, al contrario il vecchio motore di render ViewEngine non era completamente tree-shakeable. Per quanto riguarda i servizi, un servizio è tree-shakable se non viene incluso nel bundle finale se non è mai stato fatto riferimento ad esso nell’applicazione.&lt;/p&gt;

&lt;p&gt;Detto questo, i servizi definiti nell’array provider all’interno di un modulo (non di componente) &lt;strong&gt;non sono tree-shakable&lt;/strong&gt;. Ma se si registra un provider direttamente all'interno del decoratore @Injectable() utilizzando l'attributo providedIn, se non viene utilizzato nell'applicazione &lt;strong&gt;non verrà inserito nel bundle&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Questa nuova modalità è stata introdotta a partire da Angular 6, ma tutto ciò che è stato detto poco sopra in merito a “providers” e “viewProviders” è sempre valido.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Focqb1tyr6oqqiv48ltzl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Focqb1tyr6oqqiv48ltzl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusioni
&lt;/h3&gt;

&lt;p&gt;Anche se poco utilizzato abbiamo visto che esiste anche l’array “viewProviders”, che potrà venirci in aiuto per modificare il meccanismo di default del motore di dependency injection presente in Angular. Pur non essendo oggetto del presente articolo esistono anche altri metodi per cambiare tale comportamento. Infatti se si fa precedere il nome del servizio che deve essere iniettato nel costruttore con un decoratore di parametro: @Optional, @Self, @SkipSelf, @Inject, &lt;a class="mentioned-user" href="https://dev.to/host"&gt;@host&lt;/a&gt;, etc; il risultato sarà un comportamento diverso.&lt;/p&gt;

&lt;p&gt;Se volete contattarmi il mio profilo Linkedin è il seguente:&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/stefano-marchisio-sviluppatore-web-angular-javascript-aspnet-fullstack" rel="noopener noreferrer"&gt;Stefano Marchisio - sviluppatore freelance: angular | asp.net core mvc c#&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
