Disons qu'il existe un cadre simple pour afficher les popups:
@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);
}
Cela peut ensuite être utilisé comme ceci:
// 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-t-il un moyen de transférer des styles de <some-other-component>
à <happy-popup>
sans avoir à les définir à la racine de l'application?
Vous pouvez y parvenir en divisant le code de vos composants en fichiers séparés - ou fichier CSS séparé dans votre cas.
Au lieu d'écrire le style directement dans le composant - styles
, vous importeriez le fichier CSS en utilisant le styleUrls
. De cette façon, vous pouvez transmettre un ou plusieurs fichiers avec vos styles et le fichier peut être partagé entre plusieurs composants.
@Component(
styleUrls: ['./hero1.css', './folder/hero2.css'],
)
Gardez à l'esprit que les URL dans styleUrls sont relatives au composant.
Un autre avantage de l'importation du CSS avec styleUrls
est qu'il vous donne également la possibilité d'utiliser les importations dans ce fichier.
hero1.css
@import './folder/hero2.css';
FYI: C'est une pratique courante de diviser le code de vos composants en fichiers séparés.
Et puis dans votre fichier Dart, référencez-les comme:
@Component(
templateUrl: './hero.html',
styleUrls: ['./hero.css'],
)
Veuillez vous référer à AngularDart - Styles de composants pour de brèves informations à ce sujet.
Comme votre popup n'est pas un enfant du composant qui l'a ouvert, vous ne pouvez pas utiliser :: ng-deep
la seule chose que je pense que cela fonctionnera est de supprimer voir l'encapsulation de l'hôte, le popup et le composant qui ouvre le popup (essayez uniquement le popup et le composant qui ouvre le popup en premier, si cela ne fonctionne pas) t fonctionne, supprimez également l'encapsulation de l'hôte.)
@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>
''',
encapsulation: ViewEncapsulation.None // <=== no encapsulation at all
)
class HappyPopupComponent implements HasValueSetter {
Vous pouvez combiner scss avec votre code
Vous devez d'abord séparer le fichier scss que vous souhaitez partager sur l'application
Par exemple:
Dans style1.scss
.header { font-weight: bold }
Puis dans style2.scss
@import "style1"
Ou vous pouvez combiner la liste des fichiers scss dans votre code de composant en définissant dans la liste des tableaux
styleUrls: ['./style1.scss', './style2.scss'],
Voici comment vous pouvez prendre en charge manuellement la configuration de scss pour angular cli
Dans angular.json, ajoutez
"projects": {
"app": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": { // add this config
"@schematics/angular:component": {
"style": "scss"
}
},
En plus des méthodes déjà mentionnées, je suggérerais deux autres voies à explorer:
puisque Angular étend le CSS aux composants et nous aimerions le garder de cette façon votre frontière de composant de passage peut être effectuée en découvrant quelle portée Angular assignée à lui) et en ajoutant CSS de portée manuelle dans la balise globale <style>
sur la page:
@ViewChild ('popupRef') popupRef; ngAfterViewInit () {this.popupRef.nativeElement.attributes [0] .name // cela aura une valeur similaire à _ngcontent-tro-c1
avec laquelle vous devrez étendre tous vos CSS personnalisés avec. }
un inconvénient apparent de cette approche est que Angular cache la gestion CSS et donc vous devrez recourir à du JS simple pour le gérer. ( n exemple ici )
Personnellement, j'explorerais la deuxième option car elle semble être moins hacky
Vous pouvez envoyer la valeur prop au composant, qui peut être une classe personnalisée et la mettre dans votre html popop. Et puis, dans le fichier scss, ajoutez des remplacements css supplémentaires pour une classe spécifique. Ainsi, pour chaque composant personnalisé, vous pouvez avoir un code CSS personnalisé.
PS: Et oui, je suggérerais d'importer un fichier scss comme:
@Component(
styleUrls: ['./hero1.css'],
)
Il est juste préférable de séparer css de js + votre code css peut alors être beaucoup plus long, contenant tous les cas de style.