【问题标题】:Angular2 dynamic change CSS propertyAngular2动态改变CSS属性
【发布时间】:2016-01-24 12:36:18
【问题描述】:

我们正在制作一个 Angular2 应用程序,我们希望能够以某种方式创建一个全局 CSS 变量(并在分配变量时更新属性值)。

我们使用 Polymer 已经有一段时间了(现在我们正在切换到 Angular2 组件)并且我们使用了 CSS 属性(Polymer 有一些 polyfill)并且我们刚刚使用 Polymer.updateStyles() 更新了样式。

有什么方法可以实现类似的功能吗?

编辑:

我们想要类似于 Sass color: $g-main-color 或 CSS 自定义属性 color: var(--g-main-color) 的东西,并且每当我们决定更改属性的值时,例如像updateVariable('g-main-color', '#112a4f') 这样的东西会在任何地方动态更新值。所有这些都在应用程序运行时进行。

编辑 2:

我想在我的 CSS 的不同部分(主机、子元素...)中使用一些全局 CSS 变量,并且能够立即更改值 - 所以如果我更改 my-color 变量,它会在 app.xml 中的任何地方发生变化。

我将使用 Sass 语法,例如:

:host { border: 2px solid $my-color }
:host .some-label { color: $my-color }

可以使用 Angular 管道之类的东西吗? (但据说它只适用于 HTML)

:host { border: 2px solid {{ 'my-color' | cssvariable }} }
:host .some-label { color: {{ 'my-color' | cssvariable }} }

【问题讨论】:

  • 我很想知道你采取了什么方法。我们有类似的要求。
  • 我仍然没有解决方案。今天唯一合理的方法可能是使用带有某种 polyfill 的 CSS 变量......
  • 你知道任何可以在angular2中用来替换变量的polyfill吗?
  • 是否有原因使用 ngStyle 绑定到对象不起作用?这些对象可以来自任何地方,您可以在运行时随意更改它们。这样您就不必提前知道属性或值,您只需构造一个对象,将其分配给元素绑定的值,然后更改就会发生。这意味着您可以将任何类型的预制、静态或编译的 CSS 排除在外。如果这样做不好,您可以随时将所有元素绑定到 innerHTML,并通过应用您动态创建的样式跨度来更改 innerHTML。
  • 你可以使用管道:stackoverflow.com/a/66244720/1974681

标签: javascript angular dart angular-dart


【解决方案1】:

1) 使用内联样式

<div [style.color]="myDynamicColor">

2) 使用多个 CSS 类映射到您想要的并切换类,例如:

 /* CSS */
 .theme { /* any shared styles */ }
 .theme.blue { color: blue; }
 .theme.red { color: red; }

 /* Template */
 <div class="theme" [ngClass]="{blue: isBlue, red: isRed}">
 <div class="theme" [class.blue]="isBlue">

代码示例来自:https://angular.io/cheatsheet

更多关于 ngClass 指令的信息:https://angular.io/docs/ts/latest/api/common/index/NgClass-directive.html

【讨论】:

  • 这可能有效,但有一个问题 - 您必须将动态样式与 CSS 文件分开,这绝不是最好的方法。 :( 我宁愿在 CSS 中加入一些东西,但我可能不得不处理它。
  • 我不明白。使用 SASS/LESS。对于来自 JavaScript 的动态样式,我只能看到那些。无论如何,除非您做错了,否则您不能混合使用静态和动态样式。静态:css。动态:JavaScript。
  • 我确实说过,拥有 Angular2 管道之类的东西会很好——能够将其写入 CSS 文件或区域中。但这可能是不可能的,所以我必须像你在 1) 中写的那样做,也许只是在 Sass 文件中添加注释,说明有使用(或应该有)来自外部的全局变量。
  • 如果你喜欢冒险,你可以建立一个步骤来采取 SASS 并输出一个你可以导入的 JS 模块 ^_^
  • 对有数字的变量没用,你不想创建 10000 个类
【解决方案2】:

只需使用标准 CSS 变量:

您的全局 css(例如:styles.css)

body {
  --my-var: #000
}

在您的组件的 css 或其他任何内容中:

span {
  color: var(--my-var)
}

那么就可以直接用TS/JS通过给html元素设置inline style来改变变量的值:

document.querySelector("body").style.cssText = "--my-var: #000";

否则你可以使用 jQuery:

$("body").css("--my-var", "#fff");

【讨论】:

  • 这正是我想要的,谢谢分享
  • 在使用 Angular 2.0+ 时,不使用直接 DOM 操作和 jQuery 是最后的手段吗?
  • 检查一下,来自 Angular 文档的 Renderer2:angular.io/api/core/Renderer2
  • @GiantElk 对,但我只是在更改 CSS 变量值。由于 ngStyle 不支持binding CSS variables,我认为这实际上是最简单的解决方案。就个人而言,我永远不会使用像 Renderer 这样困难的 API 来更改变量的值。
【解决方案3】:

您没有任何示例代码,但我假设您想做这样的事情?

@View({
directives: [NgClass],
styles: [`
    .${TodoModel.COMPLETED}  {
        text-decoration: line-through;
    }
    .${TodoModel.STARTED} {
        color: green;
    }
`],
template: `<div>
                <span [ng-class]="todo.status" >{{todo.title}}</span>
                <button (click)="todo.toggle()" >Toggle status</button>
            </div>`
})

您将ng-class 分配给一个动态变量(您可以猜到,这是一个名为TodoModel 的模型的属性)。

todo.toggle() 正在更改 todo.status 的值,并且输入的类正在更改。

这是一个类名的例子,但实际上你可以对 css 属性做同样的思考。

我希望这就是你的意思。

这个例子是为伟大的蛋头教程here拍摄的。

【讨论】:

  • 这不是我们想要的。我们希望在 Sass color: $g-main-color 或 CSS 自定义属性 color: var(--g-main-color) 中使用类似的东西,并且每当我们决定更改属性的值时,例如像 JS updateVariable('g-main-color', '#112a4f') 这样的东西会在各处动态更新值。所有这些都在应用程序运行时进行。
【解决方案4】:

this plunker 是为了探索一种方法来做你想做的事。

这里我从父组件获取mystyle,但您可以从服务获取它。

import {Component, View} from 'angular2/angular2'

@Component({
  selector: '[my-person]',
  inputs: [
    'name',
    'mystyle: customstyle'
  ],
  host: {
    '[style.backgroundColor]': 'mystyle.backgroundColor'
  }
})
@View({
  template: `My Person Component: {{ name }}`
})
export class Person {}

【讨论】:

  • 我必须能够更改主机和子元素的样式,这是我无法使用您的解决方案所无法做到的,而且它是“CSS 区域”之外的一种杂乱的书写样式。看看编辑2。顺便说一句。与其通过属性从输入中获取颜色,不如只导入一些类并从中使用变量,因为我想要整个应用程序的全局变量。 ;)
【解决方案5】:

Angular 6 + Alyle UI

使用 Alyle UI,您可以动态更改样式

这里是demo stackblitz

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    CommonModule,
    FormsModule,
    HttpClientModule,
    BrowserAnimationsModule,
    AlyleUIModule.forRoot(
      {
        name: 'myTheme',
        primary: {
          default: '#00bcd4'
        },
        accent: {
          default: '#ff4081'
        },
        scheme: 'myCustomScheme', // myCustomScheme from colorSchemes
        lightGreen: '#8bc34a',
        colorSchemes: {
          light: {
            myColor: 'teal',
          },
          dark: {
            myColor: '#FF923D'
          },
          myCustomScheme: {
            background: {
              primary: '#dde4e6',
            },
            text: {
              default: '#fff'
            },
            myColor: '#C362FF'
          }
        }
      }
    ),
    LyCommonModule, // for bg, color, raised and others
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

HTML

<div [className]="classes.card">dynamic style</div>
<p color="myColor">myColor</p>
<p bg="myColor">myColor</p>

换风格

import { Component } from '@angular/core';
import { LyTheme } from '@alyle/ui';

@Component({ ... })
export class AppComponent  {
  classes = {
    card: this.theme.setStyle(
      'card', // key
      () => (
        // style
        `background-color: ${this.theme.palette.myColor};` +
        `position: relative;` +
        `margin: 1em;` +
        `text-align: center;`
         ...
      )
    )
  }
  constructor(
    public theme: LyTheme
  ) { }

  changeScheme() {
    const scheme = this.theme.palette.scheme === 'light' ?
    'dark' : this.theme.palette.scheme === 'dark' ?
    'myCustomScheme' : 'light';
    this.theme.setScheme(scheme);
  }
}

Github Repository

【讨论】:

  • 问题是关于 Dart 的。我想这行不通。
猜你喜欢
  • 2016-07-03
  • 2013-11-02
  • 2018-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-16
相关资源
最近更新 更多