O Que há De Novo No Angular 14 - Uma Mudança De Jogo

Descubra o que há de novo no Angular 14

LinkIntrodução

O Angular 14 foi lançado recentemente com vários recursos interessantes. E hoje, vou apresentá-los para você. São eles:

  1. Standalone Components
  2. Provedores de rota
  3. ENVIRONMENT_INITIALIZER
  4. Formulários tipados
  5. A Função inject()
  6. Configuração do título da página pela rota
  7. Autocomplete na CLI
  8. Injetores opcionais em Embedded Views

Então vamos começar!

LinkStandalone components

Para a maioria das pessoas, a mudança mais significativa nesta versão é a possibilidade de criar componentes sem @NgModule! Sim, Isso mesmo que você leu.

https://i.makeagif.com/media/8-08-2022/Em_2-b.gif

Antes do Angular 14

Se você está um pouco perdido, me deixe te mostrar uma estrutura de diretório para um componente clássico do angular:

bash
home
  |--home.component.html
  |--home.component.css
  |--home.component.ts
  |--home.module.ts

Nela, temos um arquivo .html para o template, um arquivo .css para os estilos, um arquivo .ts para o componente e outro arquivo .ts para o @NgModule. Este último arquivo importa as dependências do nosso componente, declara o componente e também pode definir alguns provedores.

Uma nova possibilidade com Angular 14

No Angular 14, podemos fazer tudo isso diretamente no componente, sem precisar de um @NgModule.

bash
home
  |--home.component.html
  |--home.component.css
  |--home.component.ts

Para fazer isso, basta definir a propriedade standalone em nosso componente como true.

TypeScript
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss'],
  standalone: true,
})

Fique atento!

Fique atento:

  1. Standalone Component não é a nova maneira de declarar componentes! Ele é outra maneira de declarar componentes. A forma clássica de definir @NgModules não será obsoleta.

De fato. Ainda usarei @NgModules em vez de standalone components porque gosto do isolamento que @NgModules fornece.

  1. Não migre todo o seu aplicativo para standalone components ainda! Eles são muito recentes e levaremos um tempo para criar convenções e definir as melhores práticas. Recomendo esperar um pouco mais antes de pular de cabeça nessa nova possibilidade.

LinkProvedores de rotas

Mas ei, se abandonarmos o @NgModule e usarmos standalone components, como podemos definir o provedor por rota, como costumávamos fazer com @NgModules?

Para resolver isso, o Angular adicionou provedores de rotas. Então, basicamente, as definições de rota agora têm uma propriedade chamada providers. Permitindo-nos fornecer valores apenas para os módulos e componentes renderizados por essa rota.

TypeScript
const NAME = new InjectionToken<string>('token');

export const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    providers: [
      {
        provide: NAME,
        useValue: 'foo'
      }
    ]
  }
];

LinkENVIRONMENT_INITIALIZER

(INICIALIZADOR DE AMBIENTE)

Outra coisa que costumávamos fazer com NgModules era executar um script de configuração quando um módulo carregado com lazy load era inicializado. Em outras palavras, o constructor de um módulo carregado com lazy load só seria executado quando o módulo fosse inicializado, e alguns desenvolvedores aproveitam isso para executar algum tipo de configuração.

TypeScript
export class HomeModule {
  constructor() {
    console.log('You can run something here');
  }
}

Como podemos fazer isso com standalone components? A solução é usar o token ENVIRONMENT_INITIALIZER.

TypeScript
const routes: Routes = [
  {
    path: '',
    pathMatch: 'full',
    component: HomeComponent
    providers:[
      {
        provide: ENVIRONMENT_INITIALIZER,
        multi: true,
        useValue: () => console.log("You can run something right here too")
      }
    ]
  }
]

Esse token nos permite fornecer uma função de configuração que será executada antes que o ambiente seja inicializado.

Se quisermos que ele seja executado quando navegarmos para uma rota, podemos fornecer esse token usando provedores de rota.

Isso tem o mesmo efeito que nossa solução anterior usando NgModule constructors e tem o benefício adicional de ser mais explícito.

LinkFormulários Tipados

Outro recurso muito aguardado do Angular 14 são os formulários tipados.

Antes da versão 14, os valores de formulário eram tipados como any. Isso significa que perdiamos toda a incrível segurança de tipagem do TypeScript.

TypeScript
  const control = new FormControl(""),
  control.value
  //=> control.value: any

A propósito, existe uma maneira segura de dizer que você não conhece o tipo de algo. Se você estiver interessado nisso, confira este vídeo de um minuto explicando as diferenças entre any e unknown.

De qualquer forma, não temos mais esse problema. Porque o Angular 14 tem tipos estritos para formulários. Portanto, se um FormControl lidar com uma string, o valor será tipado como uma string em vez de any.

TypeScript
const control = new FormControl(""),
control.value
//=> control.value: string | null

LinkFunções injetáveis

Agora, esta é a característica mais interessante para mim.

Angular 14 introduziu as funções injetáveis. E se parecem muito com os React hooks. Isso nos dá um universo de possibilidades para reutilizar nosso código, a mais relevante é que agora podemos criar funções reutilizáveis que usam injeção de dependência internamente.

TypeScript
export function getPosts() {
  const http = inject(HttpClient);
  return http.get('/api/getPosts');
}

export class HomeComponent {
  readonly posts = getPosts();
}

Se você está tão interessado em programação funcional quanto eu, sabe que isso significa muito! Mas como o tio Ben disse uma vez:

Isso cria dependências implícitas em nossa função. No entanto, espero que minhas dependências de função sejam declaradas explicitamente nos argumentos da função. Então, se vejo uma função sem argumentos, imagino que ela não tenha dependências. Mas agora, podemos criar funções que parecem puras, porém injetam muitas dependências internamente, tornando-as mais difíceis de testar e mais acopladas ao framework Angular.

Uma boa solução é seguir a mesma convenção que temos no React, prefixar essas funções com “use”. Dessa forma, você pode identificar facilmente funções que usam inject() internamente.

TypeScript
export function useGetPosts() {
  const http = inject(HttpClient);
  return http.get('/api/getPosts');
}

export class HomeComponent {
  readonly posts = useGetPosts();
}

LinkDefinir o título da página pela rota.

Uma tarefa comum em aplicações Web é alterar o título da página em cada rota.

No Angular, isso costumava ser um processo muito manual, mas agora podemos simplesmente definir o título da página na definição da rota.

TypeScript
export const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    title: 'Home',
    pathMatch: 'full'
  }
];

Mas eu sei o que você está pensando:

Não se preocupe. Angular 14 pensou em você.

Se você precisar personalizar o título dinamicamente, poderá fazê-lo estendendo a classe TitleStrategy do @angular/router e fornecer sua nova estratégia de título personalizada em vez da padrão.

TypeScript
@Injectable({ providedIn: 'root' })
export class PageTitleStrategy extends TitleStrategy {
  constructor(@Inject(Title) private title: Title) {
    super();
  }

  override updateTitle(routerState: RouterStateSnapshot) {
    const title = this.buildTitle(routerState);
    if (title !== undefined) {
      this.title.setTitle(`CompanyName | ${title}`);
    } else {
      this.title.setTitle(`CompanyName | Page without title`);
    }
  }
}

export const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    title: 'Home',
    pathMatch: 'full'
  }
];

bootstrapApplication(AppComponent, {
  providers: [
    importProvidersFrom(RouterModule.forRoot(routes)),
    { provide: TitleStrategy, useClass: PageTitleStrategy }
  ]
});

LinkAngular CLI Autocomplete

Outra coisinha legal é que agora temos um autocomplete na CLI do Angular.

Basta digitar ng no seu terminal e pressionar TAB para permitir que a CLI do Angular complete automaticamente seu comando ou forneça ajuda.

bash
> ng se
//=> If you press TAB here, the CLI will complete

> ng serve
bash
> ng
//=> If you press TAB here, the CLI will show a list of commands

> ng
  add           -- Adds support for an external library to your project.
  analytics     -- Configures the gathering of Angular CLI usage metrics.
  build         -- Compiles an Angular application or library into an outpu...
  cache         -- Configure persistent disk cache and retrieve cache sta...
  ...

Ativando o autocomplete da CLI

Para ativá-lo, você deve executar o comando ng complete e confirmar que deseja habilitar o autocomplete digitando Yes.

bash
> ng completion

? Would you like to enable autocompletion? This will set up your terminal so pressing
TAB while typing Angular CLI commands will show possible options and autocomplete arguments.
(Enabling autocompletion will modify configuration files in your home directory.)

> Yes

Por fim, reinicie seu terminal para ativar o autocomplete.

LinkInjetores opcionais em Embedded Views

Por último, mas não menos importante, agora podemos passar injetores opcionais em embedded views. No passado, tínhamos que usar outras APIs para fazer isso, como o ngComponentOutlet.

TypeScript
@Directive({ selector: '[foo]' })
export class FooDirective implements OnInit {
  constructor(
    private vcr: ViewContainerRef,
    private templateRef: TemplateRef<unknown>
  ) {}

  ngOnInit(): void {
    this.vcr.createEmbeddedView(
      this.templateRef,
      {}, // context
      {
        injector: Injector.create({
          // pass an injector :)
          providers: [
            {
              provide: 'foo',
              useValue: 'bar'
            }
          ]
        })
      }
    );
  }
}

LinkNão pare aqui

Essas foram as mudanças mais relevantes no Angular 14, na minha opinião. Se você quiser ver todas as alterações, você poderá vê-las verificando as referências.

Se você quiser se aprofundar no Angular, considere assinar nossa newsletter. É livre de spam e Mantemos os e-mails curtos e com conteúdo valioso.

E se sua empresa estiver procurando por desenvolvedores web remotos, considere entrar em contato comigo e minha equipe. Você pode fazer isso aqui.

Como sempre, as referências estão na descrição. Tenha um ótimo dia. E te vejo na próxima.

– Lucas

LinkReferências

  1. Angular 14 - Academind on Youtube
  2. O que há de novo no revolucionário Angular 14 - Andrew Rosário on Medium
  3. Novidades no Angular v14 - Vida Fullstack
  4. What is new in Angular 14? - Nevzatopcu on Medium
  5. Angular v14 is now available! - Angular Blog on Medium
  6. What’s New in Angular v14 - Netanel Basal
  7. Unleash the Power of DI Functions in Angular - Netanel Basal
  8. Getting to know the ENVIRONMENT_INITIALIZER Injection Token in Angular - Netanel Basal
  9. Typed Reactive Forms in Angular — No Longer a Type Dream - Netanel Basal
  10. Handling Page Titles in Angular - Netanel Basal
  11. Angular Standalone Components: Welcome to a World Without NgModule - Netanel Basal
  12. Pass an Injector to Embedded Views - Netanel Basal
  13. Setting page title from the route module - Brandon Roberts
  14. Standalone components with Custom Title Strategy in Angular 14

Assine a nossa Newsletter e seja avisado quando eu lançar um curso, postar um vídeo ou escrever um artigo.

Campo obrigatório
Campo obrigatório