Я работал с angular последние несколько недель, и теперь мне нужно динамически стилизовать общедоступный сайт. Администратор сайта устанавливает различные цветовые коды, а также изображение логотипа от администратора в базе данных. Они будут отражены, когда откроется общедоступный сайт.
Поскольку я работаю с asp.net, раньше я делал загрузку главной страницы, брал значения из БД и записывал их в файл .less, и пусть об этом позаботится библиотека java-script. Там все просто.
Но в моей текущей ситуации я использую sass и не могу найти способ записать переменные в файл .scss.
Я только что узнал новую вещь APP_INITIALIZER от здесь, но в конечном итоге этот пост не показывает, как писать в файле .scss.
На самом деле я думаю об этом со своими знаниями asp.net, но, возможно, я ошибаюсь или есть другой способ реализации.
Мне нужно простое решение, то, что мы делаем в asp.net, я хочу добиться этого таким же образом.
Взять значение переменной из БД через API при первой загрузке приложения.
Запишите значения в файл переменных SASS.
После этого SASS позаботится об этом, и мы получим ожидаемый результат.
Пожалуйста, дайте какое-нибудь предложение или пример, чтобы начать с.
Спасибо.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не думаю, что то, что вы хотите, будет возможно сделать ... Angular обрабатывает файлы SASS во время сборки приложения и записывает все общие результаты в простой старый файл css. Материал, специфичный для компонента, будет сгенерирован как javascript, который, в свою очередь, применит ваш стиль во время выполнения.
Следовательно, все переменные SASS, которые вам нужно настроить, должны присутствовать во время компиляции.
Однако вы можете предварительно определить свою настройку в компонентах Angular, а затем переключать ее на основе ввода (из вашей БД или откуда-либо еще), например:
// your.component.ts
@Component({
// ... component stuff
styles: ['h1.option1 {color: red;}', 'h1.option2 {color: blue;}'],
template: `
<h1 *ngIf = "optionSelection$ | async as option; else noOption"
[class.option1] = "option == 1"
[class.option2] = "option == 2">
Hey there, I'm styled!
</h1>
<ng-template #noOption>
<h1>No option received</h1>
</ng-template>
`
})
export class YourComponent {
optionSelection$: Observable<number>;
constructor(yourService: YourService){
this.optionSelection$ = yourService.getYourOption().pipe(startWith(null));
}
}
Надеюсь, это немного поможет :-)
Прежде всего, в ASP .NET может быть неплохо иметь базу данных, в которой хранятся правила CSS и другие статические ресурсы. Это потому, что это среда рендеринга на стороне сервера, так что это имеет смысл.
С другой стороны, в Angular это клиентская сторона (за исключением Angular Universal, но вам все равно придется ожидать работы в аналогичных подходах). Даже с переводами (i18n или пользовательскими) в мире Angular он, скорее всего, хранится на внешнем интерфейсе (файлы i18n .json), а не на заднем (db или около того).
Таким образом, вам придется пойти и сохранить ваши тема определенным образом, который вы предпочитаете, и динамически переключаться между ними с помощью Angular. Конечно, вы можете хранить ключи/переменные для стилей/тем, но ваш фактический код CSS по-прежнему хранится в файлах .css.
Попробуйте посмотреть этот простой пример из Переменные CSS, используемые при динамической настройке темы приложения (Angular). Это только один способ, и есть много способов сделать это, и вам, возможно, придется искать свои личные предпочтения.
Обновлено:
Мой ответ выше может иметь ошибочные последствия, но я оставлю его как есть и просто поделюсь одним опытом, связанным с этой темой.
Я работал над веб-приложением, в котором пользователь может настроить свою тему с помощью настроек, аналогичным образом. Правила CSS не хранятся в БД, но значения цвета, которые должны быть установлены для переменных sass. Был специальный сценарий, в котором будут скомпилированы сценарии CSS (был возвращен по запросу, что сделало его немного медленным, но экран-заставка просто спасает ваш день, а не скомпилирован AOT) вместе с пользовательскими значениями, которые я понятия не имею, как сделано. То же самое с переводами, я также недавно работал над проектом, где переводы из БД, но есть скрипт для запуска для каждого выпуска/развертывания, который генерирует и обновляет файлы .json в папке assets/i18n.
Это невозможно таким образом, но вместо использования переменной sass вы используете значение переменной sass. Это может быть любое значение.
Почему? потому что sass компилируется во время упаковки и, в конце концов, все равно будет генерировать плоский CSS.
Примером фреймворка, использующего этот необязательный процессор стилей, является angular.
В вашем случае я бы порекомендовал изучить динамические темы в angular, так как вам определенно нужен JavaScript. Посмотрите руководство по среде, предоставленное одним из участников.
Как объяснялось в других ответах, невозможно установить переменные SASS и обработать их на клиенте, поскольку SASS преобразуется в простой CSS во время сборки, а когда приложение работает или в браузере APP_INITIALIZER может обрабатывать только CSS.
Я вижу два варианта достижения желаемого.
Как правило, у вас будет некоторый базовый CSS для приложения, а затем вам нужно загрузить дополнительный CSS на основе настроек администратора. Что необходимо учитывать с точки зрения css, так это то, что вся специфичность css в дополнительных css должна быть больше, чем базовый css, потому что в противном случае он не переопределит базовый. Это требует базовых знаний CSS, поэтому я не буду вдаваться в подробности.
Создайте свой дополнительный css по запросу сервера. Загрузите его, когда приложение запускается с URL-адреса сервера. Перезагрузите его с помощью js, когда администратор изменит какие-либо настройки.
/additional.css (или он может быть похож на /api/theme/custom-css), который будет генерировать CSS из базы данных. Например, у вас есть background=red в db, тогда конечная точка должна вернутьсяbody {background-color: red;}
<link id = "additionalCss" rel = "stylesheet" type = "text/css" href = "additional.css" /> в <head> из index.html. И этого будет достаточно, чтобы заставить его работать.document.getElementById('additionalCss').href = document.getElementById('additionalCss').href;
Это сделает новый запрос к серверу, сервер выполнит DB -> css и вернет обновленный css, который будет применен к браузеру.
И если вы хотите быть крутым (или вам нужна поддержка больших и сложных тем), можно использовать scss. Бэкэнд должен генерировать определения переменных scss из базы данных, затем использовать какое-то приложение на стороне сервера для компиляции scss -> css, а затем возвращать скомпилированный css клиенту. Но это будет излишним, если дополнительный css достаточно прост.
Одним из важных соображений этого метода является кеширование браузера, потому что контент за дополнительным.css является динамическим, но браузер может кэшировать его, а не вызывать серверную часть и обслуживать устаревшую версию.
Если вы не хотите или не можете возиться с бэкендом. Загрузить настройки из БД по какой-либо конечной точке API в json, затем сгенерировать код css на клиенте и применить его.
{
"background": "red"
}
затем вы конвертируете это в строку как
cssCode = 'body {background-color: red}';
let additionalCssStyle = document.getElementById('additionalCss');
if (! additionalCssStyle) {
additionalCssStyle = document.createElement("style");
additionalCssStyle.id = 'additionalCss';
document.head.appendChild(additionalCssStyle);
}
additionalCssStyle.innerText = cssCode;
Хотя @Холодный Цербер предложил хороший подход и прав в отношении сохранения вещей, связанных со стилем, во внешнем интерфейсе, я предлагаю несколько способов для этого.
Как вы сказали, вам нужна различная цветовая комбинация, вы можете использовать условный CSS SASS.
body[theme = "theme1"] {
// theme 1 css
}
body[them = "theme2"] {
// theme 2 css
}
Вы можете использовать карта темы sass вместе с условным css.
Просто обновите свой атрибут, и тема будет применена автоматически.
themeChange() {
const dom = document.querySelector('body');
dom.theme = theme1; // change theme here
}
Если вы очень требовательны к стилю какого-либо элемента, который должен обновляться из серверной части (например, цветовому коду), вы можете использовать ng-стиль вместе с темой.
<some-element [ngStyle] = "{'font-style': styleExp}">...</some-element>
Вы должны использовать умную комбинацию выше, чтобы выполнить ваше требование.
Поскольку Sass — это предварительно скомпилированный CSS. мы не можем динамически изменять тему без создания отдельного файла theme.css. Здесь в игру вступает JSS. JSS — это механизм внедрения стилей на основе JavaScript, при котором CSS непосредственно вводится в файлы, которые вы его используете.
например, этот парень сделал это с помощью angular.
Документы: jss-angular, jss
ссылки: jss-with-angular