Angular 2 - 如何根据 URL 查询参数动态更改整个 CSS 样式表

我对 Angular 的世界很陌生(到目前为止我很喜欢它)。我们有一个 Angular 1 (JS) 应用程序,我们计划将其转换为最新的 Angular 2 (8.3.9) 版本。在旧应用程序中完成的一件事是使用 $scope 对象,然后根据请求 URL 中的查询参数动态设置根 index.html 中的 CSS 样式表链接。

使用 ngStyle 或 ngClass 更新文档中的单个元素很酷,但是,

我们如何处理在 Angular 2 中加载应用程序时更改整个样式表?

一切都封装在组件内部,angular.json 文件中指定的样式内置到“deployable.js”文件中。是否可以在运行时更改它?

此链接似乎是最接近的示例: Generate dynamic css based on variables angular ,但仍然没有完全解决根 index.html 文件中的问题。

当前的旧版本

网址到达:

http://someserver:port/app?css=http://linktoCSs/cssFile.css

css 查询参数被拉入一个全局变量并存储在名为 css_url 的范围内,在 index.html(起始页面)中

<link rel="stylesheet" ng-href="{{css_url}}">

并且应用程序开始使用此链接提供的任何样式表。

新的 Angular 2(版本 8.3.9)

我们想模仿我们能够在 JS 版本中实现的上述行为。从 QueryParam 中提取一个指向某个 CSS 文件的 URL,该 CSS URL 可以注入主 index.html 以一次性更改整个应用程序的样式,或者在代码中动态访问样式表以一次性更新所有内容.

简而言之,我们想要 1 个可以根据查询参数通过 CSS 文件设置样式的应用程序。

所有的想法和意见将不胜感激。


MYYA
浏览 243回答 2
2回答

九州编程

经过大量的挖掘,终于找到了我正在寻找的解决方案。它是如此直接,希望这可以帮助其他可能需要做同样事情的人..从查询参数中获取 css 路径,然后将文档注入 TS 文件...将链接附加到文档的头部。我使用 canActivate 在 Router Guard 中做到了这一点。我从 routerstatesnpshot 得到了查询参数,如下所示:在构造函数中注入 DOCUMENT(不要忘记导入)http://server.com/xxx&broker=1&client=2&css=http://cssServer.com/my_dynamic_stylesheet.css&nbsp; &nbsp;import { DOCUMENT } from '@angular/common';&nbsp; &nbsp;@Inject(DOCUMENT) private document: Document&nbsp; &nbsp;this.setDynamicStyle(state.root.queryParamMap.get('css'));&nbsp; &nbsp; setDynamicStyle(cssURL: string) {&nbsp; &nbsp; &nbsp; &nbsp; const head = this.document.getElementsByTagName('head')[0];&nbsp; &nbsp; &nbsp; &nbsp; const style = this.document.createElement('link');&nbsp; &nbsp; &nbsp; &nbsp; style.id = 'css-styling';&nbsp; &nbsp; &nbsp; &nbsp; style.rel = 'stylesheet';&nbsp; &nbsp; &nbsp; &nbsp; style.href = `${cssURL}`;&nbsp; &nbsp; &nbsp; &nbsp; head.appendChild(style);&nbsp; &nbsp; }感谢:https : //juristr.com/blog/2019/08/dynamically-load-css-angular-cli/

拉丁的传说

这似乎是一个相当普遍的问题,动态更新样式,我找不到任何人们试图覆盖 Anuglar 2 应用程序的整个 CSS 文件的地方,编译后。我最终做了什么(现在)......在 GitHub 链接上:https ://github.com/angular/angular/issues/9343 感谢:peteboere创建了一个指令,如import {Directive, ElementRef, Input} from '@angular/core';@Directive({&nbsp; &nbsp; selector: '[cssProps]',})export class CSSPropsDirective {&nbsp; &nbsp; @Input() cssProps: any;&nbsp; &nbsp; constructor(private element: ElementRef) {}&nbsp; &nbsp; ngOnChanges({cssProps})&nbsp;&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (cssProps && cssProps.currentValue)&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const {style} = this.element.nativeElement;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (const [k, v] of Object.entries(cssProps.currentValue))&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; style.setProperty(k, v);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}不幸的是,这意味着将 cssProps 放在需要样式的文档中的每个和每个元素上……例如:<div class="panel-heading" [cssProps]="cssStyling">然后我创建了一个简单的服务来以 JSON 格式获取样式,例如,{--backgroundColor: "black"}在每个组件的 css 文件中,我使用自定义 css 属性来处理这些。&nbsp; &nbsp; background: var(--backgroundColor)&nbsp; &nbsp; --backgroundColor: #008000;自我注意,在 app-root 级别执行此操作可能意味着不必为每个组件 css 文件应用样式...,但我们仍然需要将指令应用于我们想要动态设置样式的每个元素。ViewEncapsulation 将需要在较低的组件中为 NONE。然后,在每 10 秒(现在)一次 httpClient 调用中,例如:import { HttpClient } from '@angular/common/http';import { Subject, Subscription } from 'rxjs';import { Injectable } from '@angular/core';@Injectable({providedIn: 'root'})export class StyleSerivce {&nbsp; &nbsp; styleChanged = new Subject<any>();&nbsp; &nbsp; interval = new Subscription();&nbsp; &nbsp; styles:any;&nbsp; &nbsp; constructor(private httpClient: HttpClient) { }&nbsp; &nbsp; retrieveStyleFrom() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;setInterval(() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.httpClient.get('https://serverName/stylesss.json')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .subscribe(data => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(data);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.styles = data;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.styleChanged.next(this.styles);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}, 10000);&nbsp; &nbsp; }}我订阅了相应组件中的 styleChange,例如:&nbsp; &nbsp; this.styleSub = this.styleService.styleChanged.subscribe((styleNow) => {&nbsp; &nbsp; &nbsp; this.cssStyling = styleNow;&nbsp; &nbsp; })并且将 cssStyling 绑定到我的指令,当我更新存储 JSON 的数据库时,我可以动态更新屏幕......(在 10 秒过去后)这是有效的,但在每个标签上设置它以使其可从 DB/JSON 更新动态更新的痛苦是忙碌的。我不会称其为最初问题的解决方案,而是一种痛苦的解决方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript