web-dev-qa-db-fra.com

Comment appliquer des classes CSS à un autre composant dans AngularDart?

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?

8
Sergiy Belozorov

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.

  • hero.Dart
  • hero.css
  • hero.html

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.

5
Dino

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 {
1
Ron

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'],
  • Remarque: veuillez modifier le chemin en fonction de votre chemin de fichier et cela ne fonctionne que lorsque vous utilisez scss et non css

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"
                }
            },
0
Tony Ngo

En plus des méthodes déjà mentionnées, je suggérerais deux autres voies à explorer:

  1. 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 )

  1. vous pouvez essayer de définir le CSS dans @Component avant de le créer en utilisant la fabrique de décorateurs personnalisés comme dans cette réponse

Personnellement, j'explorerais la deuxième option car elle semble être moins hacky

0
timur

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.

0
Andris