【问题标题】:Dynamically set style sheet based on routing in a multi-tenant Angular 5 application基于多租户Angular 5应用程序中的路由动态设置样式表
【发布时间】:2018-01-18 21:39:01
【问题描述】:

我有一个在 Angular 5 中重新实现的多租户应用程序。每个客户端都有颜色和字体首选项。

客户端由路由决定,例如 - www.mydomain.com/client1/salesData - www.mydomain.com/client2/salesData - 等等。

我有一个 default.css 样式表,其样式如下:

.clientBackground { color: white; }

并且希望有这样的客户端样式表:

client1.css {
.clientBackground { color: blue; }
}

client2.css {
.clientBackground { color: green; }
}

然后,根据传入路由中的客户端使用适当的样式表。

关于如何做到这一点的任何想法?旧系统(Microsoft MVC)使用样式“捆绑包”,可以根据客户端选择包含。

编辑 2018 年 1 月 24 日 最终采取了与最初预期不同的方法。确定将由客户端更改的特定样式属性,例如颜色、背景颜色、字体系列等,并将它们放在一个类(ClientStyles)中。然后为每个客户端创建子类...和一个工厂,以在给定客户端 ID 的情况下返回正确的类。
然后创建了一个自定义指令 [client-styles]。它采用逗号分隔的样式属性字符串(例如 'color,font-family'),在 ClientStyles 类中找到这些属性并将它们应用于元素。如下:

import { Attribute, Directive, OnInit, AfterViewInit, Inject, HostBinding, ElementRef } from '@angular/core';
import { Observable } from 'rxjs/Rx';

    import { ClientStyles } from '../../../models/ClientStyles';
    import * as clientStyleDefs from '../../../models/client/ClientStyleDefs';

    @Directive({
      selector: '[client-styles]'
    })
    export class ClientStylesDirective implements OnInit {

      clientCode: string;
      clientStyles: ClientStyles = new ClientStyles();
      inputStyles: string[];
      sInputStyles: string;
      element: ElementRef;

      // client-styles takes a comma-delimited list of style attributes
      // to be set with client values 
      // (or defaults if client value for the attribute is not specified) 
      constructor(
        el: ElementRef, @Attribute("client-styles") styleString: string,
        @Inject(StateProvider) private _state: Observable<State>) { 
          this.element = el;
          this.inputStyles = styleString.split(',');
          this.sInputStyles = styleString;
        }

      ngOnInit() {
        this._state.subscribe(x => {
          this.clientCode = x.criteria.clientCode;      
        });

        this.clientStyles = clientStyleDefs.getClientStyles(this.clientCode);
        this.setStyles();
      }

      setStyles() {
        for (let prop in this.clientStyles) {
          // If property is in string, update that property in the element style
          if (this.sInputStyles.indexOf(prop) >= 0 && this.clientStyles[prop] != null) {
            // Heading and text font families - set the fontFamily
            if (prop == "headingFontFamily" || prop == "textFontFamily") {
              this.element.nativeElement.style["fontFamily"] = this.clientStyles[prop];
            }
            else {
              this.element.nativeElement.style[prop] = this.clientStyles[prop];
            }
          }
        }
      }
    }

【问题讨论】:

    标签: angular


    【解决方案1】:

    您应该定义一个根据活动域确定客户端类型的全局变量,您可以将其作为服务来执行。 其余的样式可以通过 ngIf 然后 ngStyle>

    轻松完成

    【讨论】:

      【解决方案2】:

      似乎是使用路由器属性的理想用例。你可以这样做:

      转到负责呈现所需视图的组件并执行此操作 -

      color: string;
      constructor(private router: Router) {
          this.setUpEvents();
      }
      
      private setUpEvents(): void {
          this.router.subscribe((value: any) => this.onNext(value)); //as router returns an observable so you need to subscribe
      }
      
      private onNext(value: any): void {
          console.log(value); //this will give you the path which has been activated and based on this you can initialize your style variable
          this.color = 'green'; //just for the sake of understanding. change it according to your need. And you can have many other css properties set here
      }
      

      现在在您的视图中使用 NgStyle,如下所示:

      <div [ngStyle]="{'color': color}"></div>
      

      【讨论】:

      • 很棒的提示。谢谢。
      • 另外,认为你需要订阅路由器事件... this.router.events.subscribe ...
      猜你喜欢
      • 2016-12-12
      • 2012-02-26
      • 1970-01-01
      • 2020-07-15
      • 1970-01-01
      • 2015-12-30
      • 2016-01-05
      • 2016-10-01
      • 1970-01-01
      相关资源
      最近更新 更多