Ответ 1
Я придумал решение, с которым я не совсем согласен.
Компонент Angular может принимать функцию в качестве шаблона и вводить с помощью $element
.
doc
Если шаблон является функцией, тогда ему вводят следующие локали:
- $element - Текущий элемент
- $attrs - Объект текущих атрибутов для элемента
Поэтому мы могли бы прикрепить основной класс для компонента (.myComponent
) в функции шаблона, а затем regex заменить все нахождение имен классов на скомпилированные имена классов.
// utils.js
function decorateTemplate(template, styles, className) {
return ['$element', $element => {
$element.addClass(styles[className]);
return template.replace(/\$\{(\w+)\}/g, (match, p1) => styles[p1]);
}];
}
// my-component.js
import style from './my-component.css';
import template from './my-component.pug';
import { decorateTemplate } from 'shared/utils';
class MyComponent {
// NO NEED to inject $element in constructor
// constructor($element) { ...
}
angular.module(name, deps)
.component('myComponent', {
// decorate the template with styles
template: decorateTemplate(template, styles, 'myComponent'),
});
// my-component.pug, with special '${className}' notation
div(class="${fooBar}") FooBar
Есть еще одно место для улучшения, которое decorateTemplate
использует замену регулярных выражений, а шаблон должен использовать специальную нотацию ${className}
для указания имен классов css-modules.
Любые предложения приветствуются.
UPDATE
Я обновил мою функцию decorateTemplate()
, чтобы использовать функции мопса, так что имена локальных классов могут быть записаны как ._localClassName
.
// utils.js
function decorateTemplate(template, styles, className) {
return ['$element', ($element) => {
$element.addClass(styles[className]);
return template.replace(/\sclass="(.+?)"/g, (match, p1) => {
let classes = p1.split(/\s+/);
classes = classes.map(className => {
if (className.startsWith('_')) {
let localClassName = className.slice(1);
if (styles[localClassName]) {
return styles[localClassName];
} else {
console.warn(`Warning: local class name ${className} not found`);
return className;
}
} else {
return className;
}
});
return ' class="' + classes.join(' ') + '"';
});
}];
}
// my-component.pug
._fooBar FooBar
Хотя это намного проще, он не устраняет причудливую нотацию (начинаем с _
для локальных имен классов) и заменяем regex.
Любые предложения приветствуются.