Se divertindo com Mixins em Angular

Mixins em Angular – O Bom, o Mau e o Feio

Christian Janker Blocked Unblock Seguir Seguindo 29 de dezembro de 2018 Foto de freestocks.org no Unsplash

No meu último post eu escrevi sobre o Statemanagement in Angular . No final, escrevi sobre um Connect Mixin que eu tinha em mente naquele momento. Ok, para ser honesto eu tinha um Componente de Ordem Superior em mente, mas isso não é tão fácil de se conseguir em Angular. Então, vamos dar um passo após o outro. O objetivo do Connect Mixin seria conectar-se a uma Loja NGRX e nos fornecer dados dela. Finalmente chegou a este writeup. Se você não ler o post inteiro, eu o encorajaria a pular para a parte do Connect-Mixin. Ou pelo menos leia a última parte: Os Mixins são ruins?

1? O que são Mixins?

A programação MixIn é um estilo de desenvolvimento de software onde unidades de funcionalidade são criadas em uma classe e então misturadas com outras classes.

Uma classe mixin é uma classe pai que é herdada de – mas não como meio de especialização . Tipicamente, o mixin exportará serviços para uma classe filha, mas nenhuma semântica será implícita sobre a criança “ser uma espécie de” o pai – [1]

Em minhas próprias palavras: Mixins são um tipo especial de herança de classes. Eles lhe dão o poder da herança múltipla e permitem que você use código de muitas classes diferentes. Mas por que?

2? Por que Mixins? ???

Eles nos permitem compartilhar o comportamento funcional cruzado. Digamos que tenhamos algumas funcionalidades genéricas para se conectar ao nosso armazenamento redux e algumas funcionalidades compartilhadas que queremos compartilhar com muitas visualizações. Uma abordagem ingênua poderia se parecer com o seguinte trecho:

Herança múltipla via estender não é permitido

Mas o compilador não está muito feliz com isso. Um erro é lançado para nós:
As aulas só podem estender uma única aula!

Como podemos resolver este problema? Mixins para o resgate ?. Vamos mergulhar diretamente em algum código. Para alcançar o comportamento desejado acima, temos que criar algumas funções que misturem (MixIn ^^) o comportamento. Essa função Mixin espera pelo menos um argumento, ou seja, a classe que queremos estender. E isso é exatamente o que está acontecendo dentro da função. Ele está retornando uma Expressão de Classe que se estende da classe determinada e adiciona um comportamento adicional sobre ela:

Amostra de MixIns

Agora podemos melhorar nossa classe base CommitView com o comportamento Connect-Mixin e o comportamento View-Mixin . Eu não quero entrar em detalhes sobre o próprio Mixins, porque já existe uma ótima introdução de Marius Schulz.

Basicamente, uma função Mixin recebe uma definição de classe e aprimora-a, estendendo-se a partir dela. No meu exemplo acima, o View-Mixin adiciona o campo viewMode e o Connect-Mixin se conecta a uma implementação de loja específica. Para a implementação completa do Connect-Mixin , navegue até 4?.

3? Mixins em material angular

Ao olhar através de alguma fonte de Material Angular, notei que existem Mixins usados também. Isso foi uma surpresa, mas faz muito sentido. Eles têm muitas funcionalidades compartilhadas entre as diferentes diretivas, como Color Mixin , Disabled Mixin , Tabindex Mixin , Error Sate Mixin ou Initialized Mixin . Construir múltiplas classes base com todas as diferentes variantes de comportamento simplesmente não seria benéfico e sustentável. Eu acho que este é um exemplo perfeito de um uso válido de Mixins.

Dê uma olhada no Color Mixin :

Antes da introdução de Mixins no Angular Material, o mesmo código era copiado e colado repetidamente em vários componentes.

4? O Connect Mixin

Como prometido acima, aqui vem o Connect Mixin. Sua tarefa é trabalhar de forma semelhante ao Connect Superior Order Component do React Redux . Ele permite que você especifique seletores e ações que são então mixadas para o determinado componente.
Nesta mini amostra, criei e conectei um componente de contador a um repositório NGRX.

Contador chato – eu sei

Vamos dar uma olhada no uso do Connect Mixin. Observe que isso mostra uma implementação muito fina de um componente contêiner . O contêiner serve exatamente um propósito: Conectar o componente do contador. Essa é uma abordagem diferente, porém limpa, dos componentes do contêiner. Por que diferente? Nos Aplicativos Angulares, muitas vezes vejo componentes de contêiner muito grandes que conectam todos os tipos de dados da loja e fazem lógica de negócios adicional neles. Eles não cumprem o Princípio da Responsabilidade Única de alguma forma.

Para poder usar a injeção de dependência do Angular, temos que adicionar a classe CounterViewBase entre e estender o container da classe Mixins criada. Isso ocorre porque as classes Mixin devem ter um construtor com um único parâmetro de repouso do tipo any[] e, portanto, não podemos injetar o Injector diretamente no Mixin.

No modelo abaixo, chamamos diretamente os métodos que foram vinculados ao contêiner por meio do Connect-Mixin. Esses métodos são acessíveis através do objeto vm . Esta é uma limitação que temos que tomar para nos mantermos compatíveis com AOT . Você pode nomear o que quiser, no entanto. Importante é apenas que a variável seja conhecida pelo modelo antecipadamente.

O modelo do contêiner do contador

O Connect-Mixin em si espera um componente que tenha um injetor, portanto criamos a interface HasInjector . Precisamos do injetor para obter o serviço de armazenamento NGRX em tempo de execução. Poderíamos ter injetado a Loja NGRX diretamente no contêiner, mas eu queria dissociar o contêiner da implementação da loja que estamos usando.

Embora eu não esteja usando o objeto vm no componente contêiner neste exemplo, os tipos Entradas <I> e Saídas <O> nos dariam um tratamento seguro contra tipos.

5? Os Mixins são ruins?

Eu tenho que admitir que eu era uma composição de favor sobre o evangelista de herança até que eu fizesse este artigo. Eu tentei evitar herança, especialmente herança múltipla, a todo custo. Mas o mundo não é apenas preto ou branco, e para bibliotecas de componentes como o Material Angular usando Múltiplas Heranças via Mixins faz sentido.

Eu não usaria excessivamente Mixins embora.

Se você precisar de muito mais comportamento dinâmico em seus componentes, eu me esforçaria para “Composição sobre herança”. A composição permite o comportamento intercambiável em tempo de execução e adere ao princípio fechado fechado.

Ainda na fila
Próximo post será sobre o tema de Mixins vs componentes de ordem superior.
Se eu mantiver o ritmo, terminarei em junho de 2019. Brincadeira ?

Confira a fonte completa do exemplo no Github

? ? Tudo de melhor para 2019 ? ?

Siga-me no Twitter 🙂

Texto original em inglês.