Mimo, że forum głównie PHPowe, to mimo wszystko taki dział istnieje i dlatego też mam nadzieję znaleźć odpowiedź na moje pytanie.

"Próbuję przenieść" (choć dokładnie powinienem nazwać to "przełożeniem", lub po prostu implementacją w innym miejscu i innej technologii) część logiki backendowej do frontendu.

Backend, to REST API na SF3 (chociaż na czym i gdzie to akurat mało ważne), frontend to Angular (4).

Co chcę uzyskać:
W Symfony mamy tagowane serwisy, tworzę sobie CompilerPass, taguję i "mam" dostępne serwisy w serwisie, tak... automagicznie. Staram się w jakiś magiczny sposób odtworzyć tą samą lub podobną logikę po stronie Angulara.

Dlaczego:
Powód jest jeden, w Symfony tagowane serwisy pomagają dodawać kolejną logikę do stosu (chociażby voter'y - bo to o nie mi akurat tutaj chodzi), brakuje mi tego po stronie frontendu w w/w frameworku. Mając 1 entry point (serwis, czy implementację poprzez dyrektywę/komponent i wtedy odwołanie się do serwisu) chciałbym pokazywać i/lub ukrywać coś w zależności od "czegoś" (tym "czymś" jest parametr z obiektem, lub sam parametr - permission).

Dlaczego tak, a nie napieprzać kod w komponencie renderującym?
Chociażby dlatego, że wiele miejsc w aplikacji wymaga sprawdzenia tych samych warunków (permission, lub permission + obiekt), a duplikowanie logiki jakoś mi nie po drodze.

Co zrobiłem (źle smile.gif ):

[JAVASCRIPT] pobierz, plaintext
  1. // ... definicja SecurityModule
  2. export const SECURITY_VOTERS = new InjectionToken('PermissionCheckerService');
  3.  
  4.  
  5. @NgModule(...)
  6. export class SecurityModule {
  7. /**
  8.   * @param {Array<IPermissionVoter>} config
  9.   * @returns {ModuleWithProviders}
  10.   */
  11. static forRoot (config: {voters: Array<Type<IPermissionVoter>>} = {voters: []}): ModuleWithProviders {
  12. return {
  13. ngModule: SecurityModule,
  14. providers: [
  15. <ClassProvider>{
  16. useClass: PermissionCheckerService,
  17. provide: SECURITY_VOTERS,
  18. useValue: config,
  19. multi: true
  20. }
  21. ],
  22. };
  23. }
  24.  
  25. /**
  26.   * @param {Array<IPermissionVoter>} config
  27.   * @returns {ModuleWithProviders}
  28.   */
  29. static forChild (config: {voters: Array<Type<IPermissionVoter>>} = {voters: []}): ModuleWithProviders {
  30. return {
  31. ngModule: SecurityModule,
  32. providers: [
  33. <ClassProvider>{
  34. useClass: PermissionCheckerService,
  35. provide: SECURITY_VOTERS,
  36. useValue: config,
  37. multi: true
  38. }
  39. ],
  40. };
  41. }
  42. }
  43.  
[JAVASCRIPT] pobierz, plaintext


[JAVASCRIPT] pobierz, plaintext
  1. // ... użycie w module głównym
  2.  
  3. @NgModule({
  4. // ...
  5. imports: [
  6. // ...
  7. // INTERNAL MODULES
  8. SecurityModule.forRoot({
  9. voters: [UserPermissionVoter]
  10. })
  11. ],
  12. providers: [
  13. UserPermissionVoter
  14. ],
  15. bootstrap: [UIView],
  16. entryComponents: []
  17. })
  18. export class AppModule {
  19. }
  20.  
[JAVASCRIPT] pobierz, plaintext


[JAVASCRIPT] pobierz, plaintext
  1. // Definicja serwisu który ma otrzymać "tagowane" serwisy
  2. import { IPermissionVoter } from '../definitions/security.interfaces';
  3.  
  4. export class PermissionCheckerService {
  5. /**
  6.   * @type {IPermissionVoter[]}
  7.   */
  8. voters: Array<IPermissionVoter> = [];
  9.  
  10. /**
  11.   * @param {string} permission
  12.   * @param resource
  13.   * @returns {boolean}
  14.   */
  15. public isGranted = (permission: string, resource: any): boolean => {
  16. let positiveCheck = 0;
  17. let negativeCheck = 0;
  18. console.log(this.voters);
  19. this.voters.forEach((checker: IPermissionVoter) => {
  20. if (true === checker.supports(permission, resource)) {
  21. if (true === checker.isGranted(permission, resource)){
  22. positiveCheck++;
  23. } else {
  24. negativeCheck++;
  25. }
  26. }
  27. });
  28.  
  29. return negativeCheck === 0 && positiveCheck > 0;
  30. }
  31. }
  32.  
[JAVASCRIPT] pobierz, plaintext


Mam świadomość, że nie wszystko jest tak, jak być powinno, wzorowałem się 3rd party libami i szczątkami dokumentacji które znalazłem.

Ktoś coś?