Вопрос:
Мне нужно руководство по написанию механизма в Angular, чтобы установить "Look and Feel" компонентов во всем мире в моем приложении. Обратите внимание, что я пытаюсь изучить @ngrx/platform, и я подумал, что это будет интересное конструктивное ограничение; однако я готов отпустить его, если это просто не имеет смысла.
Структура:
У меня есть приложение, работающее со многими компонентами. Каждый компонент в моем приложении имеет в настоящее время 3 возможных "вида и ощущения (L & F)":
- Утро (сепия)
- Вторая половина дня (белый)
- Вечер (темный)
Обратите внимание, что может быть спектр цветов, основанный на более гранулированном времени.
Эти L & Fs устанавливаются ко времени дня текущего пользователя, например, если текущее время пользователя равно 7:00, рассчитанный L & F будет установлен на "Morning". Я отслеживаю это состояние внутри ngrx/store модуля Angular под названием SundialModule
и gnomon
является механизмом редукторов и действий для состояния getting
или setting
:
солнечные часы/редукторы/gnomon.ts:
import * as gnomon from '../actions';
export interface State {
currentHour: number,
}
const initialState: State = {
currentHour: new Date().getHours()
};
export function reducer(state = initialState,
action: gnomon.Actions) {
console.log(action, 'action');
switch(action.type) {
case gnomon.MORNING:
return {
...state,
currentHour: 6,
};
case gnomon.AFTERNOON:
return {
...state,
currentHour: 12,
};
case gnomon.EVENING:
return {
...state,
currentHour: 7,
};
default:
return state;
}
}
Теперь у меня есть Angular директива атрибута под названием [sundialTheme]
, которая установит HostBinding('class') theme = 'light'
для элемента, на который он был помещен.
/директивы Sundial/theme.ts
@Directive({
selector: '[sundialTheme]'
})
export class SundialThemeDirective implements OnInit {
@HostBinding('class') theme = 'light';
private gnomon: Observable<any>;
constructor(private store: Store<fromGnomon.State>) {
this.gnomon = store.select<any>('gnomon');
}
ngOnInit() {
this.gnomon.subscribe((theme) => {
if(theme.currentHour >= 7 && theme.currentHour <= 11){
this.theme = 'sepia';
} else if( theme.currentHour >= 12 && theme.currentHour <= 18) {
this.theme = 'light'
} else {
this.theme = 'dark'
}
});
}
}
Проблема: Каждый компонент в моем приложении должен иметь этот атрибут sundialTheme
; кроме того, каждый компонент будет иметь подписку на this.gnomon = store.select<any>('gnomon');
, которая кажется дорогой/тяжелой. Наконец, и в качестве стороннего средства, это то, что каждому компоненту необходимо будет добавить мой SundialModule
в каждый функциональный модуль, и каждому компоненту потребуется набор тем для каждого времени суток:
Пример этого, каждый компонент шаблона.
note: sundialTheme
директива атрибута:
<mh-pagination sundialTheme></mh-pagination>
<canvas glBootstrap class="full-bleed" sundialTheme></canvas>
<running-head [state]="(state$ | async)" sundialTheme></running-head>
<menu-navigation sundialTheme></menu-navigation>
<folio sundialTheme></folio>
<mh-footer sundialTheme></mh-footer>
Каждый функциональный модуль с зависимостью SundialModule
:
@NgModule({
imports: [
SundialModule
],
})
export class MenuModule {
}
Каждый элемент styleUrls с sundial-links
:
обратите внимание на уродливые sundial-morning.scss
@Component({
selector: 'running-head',
templateUrl: 'running-head.component.html',
styleUrls: [
'running-head.component.scss',
'../../../components/sundial/sundial-morning.scss', // This !
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RunningHeadComponent {
}
Наконец, у меня были другие способы, предлагаемые мне:
1) Так как я использую Angular CLI, я могу добавить свои стили во всем мире и иметь директиву, устанавливающий класс на теле. Что, похоже, нарушает любые стандарты веб-компонентов.
2) Я мог бы использовать загрузчик factory в каждом компоненте styleUrls:[]
; которые я не понял, как реализовать.
3) Я мог бы следить за архитектурой компонентов материалов, которая добавляет темы непосредственно в компоненты, которые не чувствуют себя очень сухими? (однако, я слишком глубоко изучил)
4) Я мог бы сделать собственный декоратор для каждого компонента (может быть жизнеспособным, но я не уверен, как его реализовать)
Любые другие предложения? Любые лучшие практики с рассуждениями?