web-dev-qa-db-ja.com

AngularDartの別のコンポーネントにCSSクラスを適用する方法は?

ポップアップを表示するシンプルなフレームワークがあるとしましょう:

@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);
}

これは次のように使用できます:

// 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);
  }
}
...

アプリのルートでスタイルを定義せずに、<some-other-component>から<happy-popup>にスタイルを転送する方法はありますか?

8

これは、コンポーネントコードを個別のファイル、または場合によっては個別のCSSファイルに分割することで実現できます。

コンポーネントの-stylesにスタイルを直接記述する代わりに、styleUrlsを使用してCSSファイルをインポートします。これにより、スタイルを含むファイルを渡すことができ、ファイルを複数のコンポーネント間で共有できます。

@Component(
      styleUrls: ['./hero1.css', './folder/hero2.css'],
)

StyleUrlsのURLはコンポーネントを基準にしていることに注意してください。

styleUrlsを使用してcssをインポートするもう1つの利点は、そのファイル内でインポートを使用する機能も付与されることです。

hero1.css

@import './folder/hero2.css';

FYI:コンポーネントコードを個別のファイルに分割するのが一般的な方法です。

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

そして、Dartファイルでそれらを次のように参照します。

@Component(
      templateUrl: './hero.html',
      styleUrls: ['./hero.css'],
)

これに関する簡単な情報については、 AngularDart-Component Styles を参照してください。

5
Dino

ポップアップはそれを開いたコンポーネントの子ではないため、:: ng-deepは使用できません

ホスト、ポップアップ、およびポップアップを開くコンポーネントから view encapsulation を削除することだけが機能すると思います(ポップアップとポップアップを最初に開くコンポーネントのみを試してください)機能し、ホストのカプセル化も削除します。)

@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

あなたはあなたのコードとscssを組み合わせることができます

最初に、アプリ全体で共有するscssファイルを分離する必要があります

例えば:

Style1.scss

.header { font-weight: bold }

次にstyle2.scssで

@import "style1"

または、配列のリストで定義することにより、コンポーネントコードでscssファイルのリストを組み合わせることができます

styleUrls: ['./style1.scss', './style2.scss'],
  • 注:パスをファイルパスに合わせて変更してください。これは、cssではなくscssを使用する場合にのみ機能します。

これはangular cliの設定scssサポートを手動で行う方法です。

Angular.jsonに追加

"projects": {
        "app": {
            "root": "",
            "sourceRoot": "src",
            "projectType": "application",
            "prefix": "app",
            "schematics": { // add this config
                "@schematics/angular:component": {
                    "style": "scss"
                }
            },
0
Tony Ngo

すでに述べた方法に加えて、私は探求するためにさらに2つの方法を提案します。

  1. Angular CSSをコンポーネントにスコープします。これを維持するには、割り当てられているスコープAngular手動でスコープしたCSSをページのグローバル<style>タグに追加します。

    @ViewChild( 'popupRef')popupRef; ngAfterViewInit(){this.popupRef.nativeElement.attributes [0] .name //これは_ngcontent-tro-c1に類似した値を持ち、すべてのカスタムCSSをスコープする必要があります。 }

このアプローチの明らかな欠点の1つは、AngularがCSS管理を隠すため、プレーンなJSを使用して管理する必要があることです( ここでは1つの例 )。

  1. カスタムデコレータファクトリを使用して、作成する前に@ComponentでCSSを定義してみることができます この回答のように

個人的に私は2番目のオプションを検討します。

0
timur

カスタム値であるコンポーネントにprop値を送信して、それをpopop htmlに配置できます。そして、scssファイルに特定のクラスのcssオーバーライドを追加します。したがって、カスタムコンポーネントごとに、カスタムCSSコードを使用できます。

PS:そしてはい、私は次のようなscssファイルをインポートすることをお勧めします:

@Component(
      styleUrls: ['./hero1.css'],
)

Cssをjs +あなたのcssコードから分離することは、すべてのスタイリングケースを含めて、はるかに長くなる場合があります。

0
Andris