Динамически меняйте styles.scss в Angular - PullRequest
0 голосов
/ 23 октября 2018

Я хочу применить динамически Стили SCSS в соответствии с переменной, известной до угловой загрузки.Можно ли программно изменить styles.scssmain.ts перед загрузкой я хочу динамически добавить строку вроде:

@import 'assets/styles/customerA/_themes.scss';
                       or 
@import 'assets/styles/customerB/_themes.scss';

в зависимости от значения переменной, поступающей с сервера.

Если вышеприведенное невозможно, есть лилюбой способ заполнить styles.scss содержимым другого файла, который будет определен на сервере?Я хочу изменить styles.scss, а не любой другой "локальный" файл scss.

Ответы [ 5 ]

0 голосов
/ 01 декабря 2018

После долгих попыток я нашел ответ в CSS variables.Это именно то, что я искал!Вы можете изменить их во время выполнения, и, следовательно, динамическое тематирование выполнимо.Это очень хорошая статья, описывающая шаги в Angular:

https://medium.com/@amcdnl/theming-angular-with-css-variables-3c78a5b20b24

0 голосов
/ 01 ноября 2018

Просто идея, которая может сработать.( origin )

Предполагается, что он предназначен для изменения файла среды, но я предполагаю, что он должен работать и для стилей.

Вы можете изменить файл стилей, используяfileReplacements в angular.json, но для этого потребуется каждый раз перестраивать приложение.

В вашем файле angular.json:

projects> public> architect> build>конфигурации

"customerA": {
  "fileReplacements": [
    {
      "replace": "src/styles.scss",
      "with": "assets/styles/customerA/_themes.scss"
    }
  ]
},
"customerB": {
  "fileReplacements": [
    {
      "replace": "src/styles.scss",
      "with": "assets/styles/customerB/_themes.scss"
    }
  ]
}

проекты> общедоступные> архитектор> обслуживание> конфигурации

"customerA": {
  "browserTarget": "public:build:customerA"
},
"customerB": {
  "browserTarget": "public:build:customerB"
},

Теперь вы можете запустить ng serve -c customerA или ng serve -c customerB, чтобы получитьсоответствующая таблица стилей.

Когда вы будете готовы к производству, вы можете либо дважды развернуть вручную, либо попробовать следовать этой идее для перевода углового приложения .

PS Если этоэто всего лишь несколько стилей, которые вам нужно изменить, я могу предложить вам использовать переменные css .

0 голосов
/ 25 октября 2018
  ngOnInit() {
    // Do some stuff to figure out which css url you want
    this.cssUrl = '/assets/styles1.css';
  }

В вашем HTML-файле

<link rel="stylesheet" [href]='sanitizer.bypassSecurityTrustResourceUrl(cssUrl)'>
0 голосов
/ 26 октября 2018

У меня есть 2 идеи, с которыми вы могли бы поиграть ...

1) У угловых компонентов есть styleUrls, который может принимать файлы .scss.Однако не похоже, что вы можете легко заменить свойство stylesUrl.Однако вы можете легко поменять сам компонент ...

По сути, ваше реальное приложение будет упаковано в "оболочку", единственной обязанностью которой является получение правильного файла .scss.В частности, он будет обернут в 2 разных оболочки, по одному для каждого стиля.

@Component({
  selector: 'style-one-page',
  templateUrl: './app.component.html',
  styleUrls: ['./app-style-one-page.scss']
})
export class WrapperStyleOneComponent extends PageComponent {}

@Component({
  selector: 'style-two-page',
  templateUrl: './app.component.html',
  styleUrls: ['./app-style-two-page.scss']
})
export class WrapperStyleTwoComponent extends PageComponent {}

Тогда тривиально поменять местами 2 компонента.

2) Моя вторая идея будетчтобы использовать темы угловых материалов, их можно легко поменять местами:

@import '~@angular/material/theming';
@import 'themes-palettes';
@import 'themes-common';
@include mat-core();

@function custom-light-theme() {
  @return (
    primary: $primary-palette,
    accent: $accent-palette,
    warn: $warn-palette,
    foreground: $foreground-palette,
    background: $background-palette,
    is-dark: false
  );
}

$custom-light-theme: custom-light-theme();
@include angular-material-theme($custom-light-theme);

.dark-theme {
  $mat-dark-theme: mat-dark-theme($dark-primary-palette, $dark-accent-palette, $dark-warn-palette);
  @include angular-material-theme($mat-dark-theme);
}
0 голосов
/ 25 октября 2018

Я бы порекомендовал следовать общей форме веб-сайта Angular Material: https://github.com/angular/material.angular.io/blob/master/angular.json. Стоит клонировать этот репо и поиграть с ним локально.Есть несколько движущихся частей.

В вашем файле angular.json вы добавите CSS следующим образом.Обратите внимание, что вам нужно будет скомпилировать ваш scss в css отдельно, чтобы это работало.Они делают это в скрипте tools/build-theme.sh.:

{
  "input": "src/assets/customer-1-theme.css",
  "lazy": true,
  "bundleName": "customer-1-theme"
},
{
  "input": "src/assets/customer-2-theme.css",
  "lazy": true,
  "bundleName": "customer-2-theme"
},

Затем посмотрите на их менеджер стилей: https://github.com/angular/material.angular.io/blob/master/src/app/shared/style-manager/style-manager.ts

Вы создадите функцию для динамического добавления и удаления этой таблицы стилей по мере необходимости:

function createLinkElementWithKey(key: string) {
  const linkEl = document.createElement('link');
  linkEl.setAttribute('rel', 'stylesheet');
  linkEl.classList.add(getClassNameForKey(key));
  document.head.appendChild(linkEl);
  return linkEl;
}

Затем в ThemePicker вы настроите наблюдаемое для управления настройкой и удалением темы.Смотрите (https://github.com/angular/material.angular.io/blob/master/src/app/shared/theme-picker/theme-picker.ts):

installTheme(themeName: string) {
  const theme = this.themes.find(currentTheme => currentTheme.name === themeName);
  if (!theme) {
    return;
  }
  this.currentTheme = theme;
  if (theme.isDefault) {
    this.styleManager.removeStyle('theme');
  } else {
    this.styleManager.setStyle('theme', `assets/${theme.name}.css`);
  }

  if (this.currentTheme) {
    this._themeStorage.storeTheme(this.currentTheme);
  }
}

Лично я пошел по этому пути немного по-другому, но это означало, что scss компилируется в один файл css, и класс выбирается динамически. Их путь добавляет дополнительную сборкушаг, но допускает отложенную загрузку скомпилированного scss.

Управление глобальными стилями

В их файле angular.json вы заметите, что у них есть main.scssкоторый используется независимо от того, какой вторичный стиль выбран. Этот файл будет обрабатывать любые глобальные темы, которые вам нужны. Обратите внимание, что в main.scss они импортируют несколько Sass partials. Они позволяют им устанавливать глобальные стили для любой темы. Вы можете узнать, как этиосновная причина того, что они используют партиалы, заключается в том, что они могут передавать переменные из вторичных файлов sass в эти партиалы с помощью mixins.

@mixin material-docs-app-theme($theme) {
  $primary: map-get($theme, primary);
  .docs-primary-header {
    background: mat-color($primary);

map-get - это функция Sass, котораяпозволяет вам определять объект и использовать его значения в Mixins. У материального дизайна есть функция sass, которую они используют здесь, но вы могли быиспользуйте более простой метод, возьмите пользовательский цвет в вашем файле main.scss.В вашем стиле style-a / style-b scss создайте собственную тему.

$my-custom-theme: (
  background-color: #ffff,
  button-background: rgba(200, 200, 200, 0.6),
  foreground: #34383c
);

Затем вы измените их @include на:

@include material-docs-app-theme($theme, $my-custom-theme);

material-docs-app-Тематический миксин изменится на:

@mixin material-docs-app-theme($theme, $my-custom-theme) {
  $background-color: map-get($my-custom-theme, background-color);
  .our-background {
    background-color: $background-color;
  }

Это позволяет вам определять собственные цвета в отдельных загруженных лентами стилей и размещать их в глобальном файле main.scss.Mixins и Partials от Sass делают это возможным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...