35 votes

Style d’extension / substitution de composant angular2 réutilisable

En supposant que nous voulons utiliser un composant à partir d'une bibliothèque dans angular2 (exemple de material2). Le composant d'annotation ressemble à ceci:

@Component({
  moduleId: module.id,
  selector: 'md-input',
  templateUrl: 'input.html',
  styleUrls: ['input.css'],
  providers: [MD_INPUT_CONTROL_VALUE_ACCESSOR],
  host: {'(click)' : 'focus()'}
})

Ce composant est livré avec un "défaut" de la feuille de style, l'entrée".css". Si nous utilisons cette composante dans notre application, nous avons susceptibles de vouloir remplacer/étendre certains du style, sans avoir à les copier et à manipuler le composant lui-même. Comment faire cela?

Solution Possible 1: Définir l'Encapsulation de "ViewEncapsulation.Aucun":
Ce n'est pas vraiment une solution, juste une solution de contournement.

Solution 2: Utilisation de "::de l'ombre" ou "/deep/" dans le CSS:
Fonctionne aussi, mais sa obsolète selon WebComponent spec.

Solution 3: Utiliser le CSS et remplacer le composant CSS:
Fonctionne aussi, mais il viole le shadow DOM concept.

Solution 4: Remplacer directement dans le modèle de composant parent:

Exemple:

<my-cmp [font-size]="100"></my-cmp>

N'est pas vraiment adapté si nous faisons beaucoup de raisons.

Solution 5: Remplacer ou étendre le "@Composante" définition avec un supplément de feuille de style en quelque sorte:
Cela semble être la seule solution correcte (au moins pour moi). Mais je n'ai aucune idée de comment faire cela...

Tous les conseils sur ce point? Peut-être que j'ai quelque chose de mal... Merci.

18voto

Mohammed Safeer Points 1533

Dans Angular 4, nous pouvons remplacer le style avec le sélecteur de pseudo-classe ::ng-deep de la feuille de style de classe héritée.

 :host ::ng-deep element {
    //your style here
}
 

Pour plus d'informations, consultez http://blog.angular-university.io/angular-ngclass-ngstyle/

11voto

thierry templier Points 998

Pour la solution 5, vous devez créer une sous-classe de la cible de composant, de créer un décorateur qui gère / remplace les métadonnées pour la sous composante.

Voici un exemple:

@CustomComponent({
  styleUrls: ['css/style.css']
})
export class OverridenComponent extends SomeComponent {
}

L' CustomComponent décorateur devrait ressembler à ceci:

export function CustomComponent(annotation: any) {
  return function (target: Function) {
    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);

    var parentAnnotation = parentAnnotations[0];
    Object.keys(parentAnnotation).forEach(key => {
      if (!isPresent(parentAnnotation[key])) {
        annotation[key] = parentAnnotation[key];
      }
    });
    var metadata = new ComponentMetadata(annotation);

    Reflect.defineMetadata('annotations', [ metadata ], target);
  }
}

Voir cette question pour plus de détails:

8voto

Günter Zöchbauer Points 21340

Solution 2: Utilisation de "::de l'ombre" ou "/deep/" dans le CSS:

Ceci s'applique uniquement si vous utilisez ViewEncapsulation.Native.

Si vous utilisez ViewEncapsulation.Emulated (par défaut), alors Angulaire utilise sa propre interprétation de l' /deep/ et ::shadow et l'amortissement ne s'applique pas.

Si vous utilisez ViewEncapsulation.Native alors vous êtes actuellement hors de la chance parce que le navigateur natif ::shadow et /deep/ de profondeur sont obsolètes et Angulaire ne permet pas encore de fournir un soutien pour themeing soutien pour ViewEncapsulation.Native comme par exemple en Polymère avec (polyfilled) CSS variables et mixin.

7voto

seescode Points 1435

À partir de la version 2.3 angulaire, nous pouvons utiliser l'héritage des composants. Afin de réaliser votre solution 5, nous pourrions le faire.

 //This is our base component that we want to override
@Component({
  selector: 'pagination',
  templateUrl: './pagination.component.html',
  styleUrls: ['./pagination.component.css']
})
export class PaginationComponent {
}


//This inherits from our base component and uses a different style sheet.
@Component({
  selector: 'pagination2',
  //This is sharing the template with the parent class.  Note
  //this needs to be included since templateUrl doesn't automatically
  //inherit.
  templateUrl: './pagination.component.html',
  //This is using a unique css file 
  styleUrls: ['./pagination2.component.css']
})
export class PaginationComponent2 extends PaginationComponent {
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X