簡體   English   中英

一個組件的 CSS 導致另一個組件出現不需要的格式

[英]CSS of one component causing unwanted formatting in another

我還在 Angular、CSS 和 HTML(這三個都是新的)中學習,所以請耐心等待我。

我收到了一些代碼,並被賦予了修復某些格式的任務。

這是問題所在:

當頁面首次加載時,頁面 header 有一些填充。 見左下圖。

但是,當我導航到另一個包含以下代碼的頁面時:

/* Removing padding and scroll bar from main page */
::ng-deep html > body > main#app-content {
    overflow-y: hidden;
    padding: 0;
}

然后導航到任何其他組件/頁面,填充消失,所有內容一直移動到屏幕左側,這非常煩人。 見右下圖。 注意:有人告訴我這是導致這種情況的代碼,實際上我不知道它實際上在做什么(除了設置填充和 y 滾動)。

這張圖片顯示了兩個組件/頁面,在我使用上面的代碼訪問頁面之前(顯示在圖片的左側),然后在我使用上面的代碼導航到該頁面之后(顯示在圖片的右側) . 請注意,綠線供參考以顯示填充如何消失。

在此處輸入圖像描述

因此,當我使用上面的代碼訪問頁面后導航回它時,我想恢復原來的填充/格式。

另外,有人可以向我解釋為什么要這樣做嗎? 如果可能的話,代碼的實際含義是什么? 以下是一些具體問題:

  1. 我怎樣才能阻止這種情況發生在另一個頁面上?
  2. “::ng-deep html > body > main#app-content”是什么意思?
  3. 大號有什么作用?

TLDR:這是一個 stackblitz,其中包含一個示例,說明如何使用服務而不是::ng-deep來編輯全局樣式。 https://stackblitz.com/edit/angular-ivy-p4pkdu?file=src/app/app.component.html


::ng-deep是一個 angular 功能,它促進以下 css 在全球范圍內應用(在您的應用程序中的任何地方)。 真的應該避免,因為通常有更好的方法來應用全局 styles。這個功能實際上已被棄用,我將在這個答案的末尾放置一個替代方案。

html > body > main#app-content只是一個 CSS 選擇器。 在本例中,我們選擇了id app-contentmain元素,它以body作為父元素,以html作為父元素。 這是 CSS 語法的一個很好的參考: https://www.w3schools.com/cssref/css_selectors.asp

所以我們將這些 css styles 應用到類型為main且 ID app-content的 html 元素,該樣式是全局應用的,因此在封裝組件被銷毀后它仍然會保留。


::ng-deep的一個更好的替代方法是使用服務來編輯全局 styles。首先,任何全局 styles 都應該存儲或導入到全局 styles 文件中,通常在 angular 項目中稱為styles.css 如果你只需要一個組件中的樣式,你可以將這個 css 放在相應的組件 css 文件中。 我們將其聲明為 class 以便我們可以將其動態添加到元素中。

styles.css

.noPaddingOrScrollbar {
  overflow-y: hidden;
  padding: 0;
}

然后使用ng g service <serviceName>通過 cli 生成服務。 例如,要在名為 services 的文件夾中生成名為globalStyleServiceservices ,我們執行ng g service services/global-style 我們將向我們的服務添加一個 boolean 以指示我們是否要應用該樣式。

需要注意的是,我們需要使用setTimeout來設置 boolean,以避免可怕的NG0100: Expression has changed after it was checked錯誤。 setTimeout將默認為零超時,但仍會延遲代碼執行,直到 Angular 完成一輪更改檢測之后。

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class GlobalStyleService {
  private _noPaddingOrScrollbar = false;

  set noPaddingOrScrollbar(value: boolean) {
    //Delay setting until after change detection finishes
    setTimeout(() => (this._noPaddingOrScrollbar = value));
  }

  get noPaddingOrScrollbar() {
    return this._noPaddingOrScrollbar;
  }

  constructor() {}
}

現在您需要找到這個main#app-content元素實際位於哪個組件中。 它將位於父組件之一的 html 文件中。 然后就可以在這個父組件的ts文件中注入服務,在組件的html文件中動態設置class。

父組件ts文件

export class ParentComponent {
  constructor(public globalStyle: GlobalStyleService) {}
  ...
}

我們使用 angular 指令[class.className]="boolean"來動態設置 class。

父組件 html 文件

...
<main
  id="app-content"
  [class.noPaddingOrScrollbar]="globalStyle.noPaddingOrScrollbar"
></main>
...

現在您可以在應用程序的任何位置添加或刪除此 class。 所以在包含 hacky css 的組件中,我們注入服務,在ngOnDestroy期間添加樣式並在ngOnInit期間刪除它。 當然,還要從 css 文件中刪除::ng-deep語句。

子組件ts文件

export class MyComponent implements OnInit, OnDestroy {
  constructor(private globalStyle: GlobalStyleService) {}

  ngOnInit(): void {
    this.globalStyle.noPaddingOrScrollbar = true;
  }

  ngOnDestroy(): void {
    this.globalStyle.noPaddingOrScrollbar = false;
  }
  ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM