Digamos que exista uma estrutura simples para exibir pop-ups:
@Component(
selector: 'popup-host',
template: '''
<div class="popup-container">
<ng-template #popupRef></ng-template>
</div>
''',
styles: ['.popup-container { position: absolute; top: 100; left: 100; z-index: 100; }'],
)
class PopupContainerComponent {
final PopupController _controller;
final ComponentLoader _loader;
PopupContainerComponent(this._controller, this._loader);
void ngOnInit() {
_controller.container = this;
}
@ViewChild('popupRef', read: ComponentRef)
ComponentRef popupRef;
void render(PopupConfig config) {
final componentRef = _loader.loadNextTo(config.factory, popupRef);
if (componentRef.instance is HasValueSetter) {
componentRef.instance.value = config.value;
}
}
}
@Injectable()
class PopupController {
PopupContainerComponent _container;
set container(PopupContainerComponent container) => _container = container;
void showPopup(PopupConfig config) {
container.render(config);
}
...
}
class PopupConfig {
final ComponentFactory factory;
final dynamic value;
PopupConfig(this.factory, [this.value]);
}
abstract class HasValueSetter {
set value(dynamic value);
}
Isso pode ser usado assim:
// Somewhere in the root template
<popup-host></popup-host>
// In popup.dart
@Component(
selector: 'happy-popup',
template: '''
<div class="header">This is the popup content.</div>
<div class="main">The value is {{value}}.</div>
<div class="footer">I am happy!</div>
''',
)
class HappyPopupComponent implements HasValueSetter {
@override
dynamic value;
}
// In some_other.dart
@Component(
...
styles: [
'.header { font-weight: bold }',
'.main { color: red }',
'.footer { color: green; font-style: italic }',
],
...
)
class SomeOtherComponent {
final PopupController _popupController;
...
SomeOtherComponent(this._popupController, ...) ...;
void displayPopup() {
_popupController.showPopup(HappyPopupComponentNgFactory, 42);
}
}
...
Existe uma maneira de encaminhar estilos de <some-other-component>
para <happy-popup>
sem precisar defini-los na raiz do aplicativo?
fonte
PopupConfig
. É possível personalizar astyleUrls
propriedade em um componente em tempo de execução?styleUrls
dinamicamente no tempo de execução. Existem várias maneiras de fazer isso. Sugiro que você procureAngular dynamic styleUrls
algumas idéias e veja qual delas se encaixa melhor em você. Em relação à segunda questão. Se esse for o caso, eu importaria o arquivo de estilo pop-up compartilhado + o arquivo de estilo em que sobrescrevi os estilos que desejo alterar para um componente específico.styleUrls
no tempo de execução, não é? E se dois pop-ups aparecerem ao mesmo tempo, por exemplo, um abre outro e precisam ser estilizados de maneira diferente? Se eu modificar ostyleUrls
, não seria o estilo de ambos? Por fim, não consegui encontrar um bom artigo sobre como modificar dinamicamentestyleUrls
sem hacks. Parece não ser suportado pela Angular nativamente.Como seu pop-up não é filho do componente que o abriu, você não pode usar :: ng-deep
a única coisa que acho que funcionará é remover o encapsulamento de exibição do host, o pop-up e o componente que abre o pop-up (tente apenas o pop-up e o componente que abre o pop-up primeiro, se isso não funcionar, remova o encapsulamento do host também.)
fonte
header
,main
, efooter
pode-se facilmente de estilo tais componentes aliás. Talvez alguém possa tentar usar nomes mais específicos para evitar conflitos, mas eu preferiria uma solução que mantenha o encapsulamento.ViewEncapsulation
é um grande não-não para aplicativos de tamanho médio ou grande. É preciso um cuidado especial ou todo o seu estilo ficará confuso a longo prazo. (ex: nomes genéricos de classe). E eu discordo que é a única solução para os requisitos dele.Você pode combinar scss com seu código
Primeiro, você precisa separar o arquivo scss que deseja compartilhar no aplicativo
Por exemplo:
Em style1.scss
Em seguida, em style2.scss
Ou você pode combinar a lista de arquivos scss no código do componente, definindo na lista de matriz
Isto é como você pode configurar manualmente o suporte do scss para o angular cli
Em angular.json, adicione
fonte
@import
declarações. Mas, assim como a resposta do @Dino, eu me pergunto se é possível não precisar codificar a URL do estilo no componente pop-up, mas lê-laPopupConfig
e atribuí-la de alguma forma em tempo de execução?Você pode enviar um valor prop para o componente, que pode ser uma classe personalizada e colocá-lo no seu pop-up html. E então, no arquivo scss, adicione substituições extras de css para uma classe específica. Portanto, para cada componente personalizado, você pode ter um código CSS personalizado.
PS: E sim, eu sugeriria importar arquivos scss como:
É melhor separar css de js + seu código css, pois pode demorar muito mais, contendo todos os casos de estilo.
fonte
Além dos métodos já mencionados, sugiro mais dois caminhos a serem explorados:
desde que o Angular seleciona o CSS para os componentes e gostaríamos de mantê-lo dessa maneira, o limite do componente de cruzamento pode ser feito, descobrindo qual escopo o Angular atribuiu a ele e adicionando CSS com escopo manual à
<style>
tag global na página:@ViewChild ('popupRef') popupRef; ngAfterViewInit () {this.popupRef.nativeElement.attributes [0] .name // isso terá um valor semelhante ao
_ngcontent-tro-c1
qual você precisará definir todo o seu CSS personalizado. }Uma desvantagem aparente dessa abordagem é que a Angular oculta o gerenciamento de CSS e, portanto, você precisará recorrer ao JS simples para gerenciá-lo. ( um exemplo aqui )
Pessoalmente, eu exploraria a segunda opção, pois parece ser menos invasiva
fonte