簡體   English   中英

Angular:如何添加全局 CSS(例如添加到正文),但僅針對一個特定頁面?

[英]Angular: How to add global CSS (e.g. to the body), but only for one specific page?

我怎樣才能在角添加單獨的CSS一個頁面?

這是我需要的 CSS,根據如何從打印頁面中刪除 URL?

@media print{
    @page{
        margin:0;
    }
    body{
        margin:30px;
    }
}

但是使用::ng-deepViewEncapsulation.None將 CSS 放入組件在這里ViewEncapsulation.None ,因為當導航離開頁面時,頁面的 CSS 不會被刪除。

我添加了一個Stackblitz ,它清楚地解釋了這個問題。


我想出了一個潛在的解決方案,但它不起作用:

  encapsulation: ViewEncapsulation.None

   ...      

  constructor(private renderer: Renderer2) {
    this.renderer.addClass(document.body, 'special-print');
   }

  ngOnDestroy() {
    this.renderer.removeClass(document.body, 'special-print');
  }
  ....
  ....
  ....
  @media print{
    @page{
        margin:0;
    }
    body.special-print{
        margin:30px;
    }
  }

為什么它不起作用:

雖然它對<body> CSS 有幫助,但@page CSS 沒有幫助。 也許這個問題可以更好地概括為“如何添加全局 CSS,但在我們離開頁面時將其刪除?”。

解決了!

我們將<style>塊直接打印到組件的 HTML 中,因此當組件被移除時,我們的<style>塊也會被移除。 通常這行不通,但多虧了DomSanitizer.bypassSecurityTrustHtml ,Angular 在運行優化時不會破壞我們的代碼。)

這是一個StackBlitz

首先,創建一個新組件來處理工作:

component.ts: (This is all we need. We don't need an HTML or style.css file.)
//Inside  your local component, place this HTML 
//<app-local-css [style]="'body{background:green !important;}'"></app-local-css>
// OR
//<app-local-css [scriptURL]="'/path/to/file.css'"></app-local-css>

@Component({
  selector: "app-local-css",
  template: '<span style="display:none" [innerHTML]="this.safeString"></span>'
})
export class LocalCSSComponent implements OnInit {
  constructor(protected sanitizer: DomSanitizer) {}
  @Input() scriptURL?: string;
  @Input() style?: string;

  safeString: SafeHtml;
  ngOnInit() {
    if (this.scriptURL) {
      let string = '<link rel="stylesheet" type="text/css" href="' + this.scriptURL + '">';
      this.safeString = this.sanitizer.bypassSecurityTrustHtml(string);
    } else if (this.style) {
      let string = '<style type="text/css">' + this.style + "</style>";
      this.safeString = this.sanitizer.bypassSecurityTrustHtml(string);
    }
  }
}

然后像這樣使用它:

mySample.component.html:

<app-local-css [style]="'body{background:green !important;}'"></app-local-css>
// OR
<app-local-css [scriptURL]="'/path/to/file.css'"></app-local-css>

Angular 正在做客戶端渲染,這是個壞消息,因為你沒有單獨的頁面。 不過,您有幾種可能的解決方案:

1. 單獨的頁面

您可以使用或不使用 Angular 創建另一個頁面,其中包含您需要的 CSS 並加載該頁面。 在實現此目的的最簡單方法中,另一個頁面將具有不同的 URL。 如果您不喜歡使用不同的 URL,那么您可以隱藏頁面的內容並在iframe顯示另一個頁面。 誠然,這將是一個笨拙的解決方案,但它是一個解決方案。

2. 客戶端CSS渲染

除了加載 CSS,您還可以擁有一個控制全局 CSS 規則的組件,並與您的視圖名稱匹配。 您會將模板值呈現給屬性,例如:

@media print{
    @page{
        margin:0;
    }
    body{
        margin:30px;
    }
}

當您訪問需要激活它的頁面時,您只需使用基於模板生成並添加到headstyle HTML 元素初始化一個屬性。 一旦您離開給定的視圖,您的組件將檢測到該事件並remove()該元素。 如果你選擇這個解決方案,那么明智的做法是確保你在更一般的條款上支持它,這樣如果一些新的視圖將有他們自定義的全局 CSS,那么它們將來會很容易集成到你的項目中.

3. 身體類

每當要更改樣式時,您都可以在body添加/刪除一些custom-print或任何類。 通過這種方式,您可以將 CSS 僅添加一次到您的 HTML 並相應地更改規則,例如:

body.custom-print {
    margin: 30px;
}

這將是一個巧妙的解決方案,但在您的情況下,問題是您也有一個@page規則,我不確定您如何使其依賴於正文類或其他一些 HTML 屬性。 如果我是你,我會為此做很多實驗。

4. iframe 暫存

您可以避免在您的主頁中使用該 CSS,但是會有一個隱藏的iframe ,您可以在其中擁有 CSS,並且只需將內容復制到 CSS 中,一旦加載,就打印出來。

不要從蘋果改變整個身體。 相反,需要進行一些更改。

  1. 在 app 組件中,為你是否在 Apple 上持有一個布爾值,並為 scss 中定義的類使用 ngClass。

  2. 在 appComponent 中跟蹤您所在的路線,並相應地設置 isApple

  3. 在所有 html 周圍添加一個 div,以便容器采用全尺寸

  4. 添加全局 html,body 設置高度為 100% 讓你到處都能看到顏色

  5. 刪除蘋果中的身體覆蓋

所以,appComponent.ts:

  isApple: Boolean;
  constructor(router: Router) {
    router.events.subscribe(v => {
      if (v instanceof NavigationEnd) {
        this.isApple = v.url === "/apple";
      }
    });
  }

appComponent.html:

<div [ngClass]="{'red':isApple}" class="container">
    <p>
        There are two components: Apple and Banana. Switching between them will show
        the problem.
    </p>

    <router-outlet></router-outlet>
</div>

應用組件.scss


.red {
  background-color: red;
}

.container {
  height: 100%;
}

apple.component.scss(移除主體)

/*Sample "global" CSS, that affects something outside the current component.*/
::ng-deep {
  @media print {
    @page {
      margin: 0;
    }
  }
}

style.scss(全局)

html, body {
  height: 100%;
}

您可以在此 Stackblitz 鏈接中完全看到這一點

您可以在組件中添加不同的 css 文件(例如 app-task.component.ts):

@Component({
  selector: 'app-task',
  templateUrl: './app-task.component.html',
  styleUrls: ['./app-task.component.scss', './styles2.scss', './styles3.scss']
})

在此示例中,樣式文件與組件位於同一文件夾中,但這不是最佳選擇:例如,您必須將文件放在資產中。 另外,請注意樣式的線程,因為您放置的第一個將放在第二個之前(顯然)。

暫無
暫無

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

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