2

The use case is as follows: We would like to have elements hidden or shown, based on the user's permissions.

The ideal way would be something like this:

<div if.bind="foo != bar && hasPermission('SOME_PERMISSION')"></div>

hasPermission() would in that case be a function that was automatically injected into all viewmodels.

Is that possible? I know we could use base classes for this, but we'd like to avoid that to stay as flexible as possible.

dabide
  • 996
  • 1
  • 6
  • 18
  • may be duplicate of http://stackoverflow.com/questions/32066809/global-functions-in-aurelia – rab Mar 09 '16 at 11:25
  • I saw that one, but it seems to be a different question. The accepted answer requires injecting it manually into each viewmodel, as far as i can see. That doesn't solve our use case. – dabide Mar 09 '16 at 11:52
  • 1
    This is something that is actively being designed/discussed. To make the progress on this more transparent I've opened an issue in templating: https://github.com/aurelia/templating/issues/287 – Jeremy Danyow Mar 09 '16 at 12:30

3 Answers3

2

If you're willing to pay the price of a global function (global as in window), import it in your app-bootstrap file, like so:

has-permission.js

export function hasPermission(permission) {
  return permission.id in user.permissions; // for example...
}

main.js

import 'has-permission';

export function configure(aurelia) {
  // some bootstrapping code...
}

If the service you want to publish globally is a view, you can sidestep exposing it on the window and tell Aurelia's DI to make it available everywhere so you won't have to declare it in every dependent client.

To do so, pass its module ID in the FrameworkConfiguration#globalResources() configuration function:

export function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .globalResources('my-kick-ass-view', 'my-awesome-converter');

  aurelia.start().then(a => a.setRoot());
}
Eliran Malka
  • 15,821
  • 6
  • 77
  • 100
1

If you have a service which deals with user permission, it can be injected in all your view-models.

export class UserPermissionService
{
     hasPermission(user, permission) 
     {
         return false;
     }
}

@inject(UserPermissionService)
export class Users {  
  userPermissionService;
  constructor(userPermissionService) {
    this.userPermissionService = userPermissionService;
    ...
  }
  hasPermission(user, p) 
  { 
     return this.userPermissionService.hasPermission(user, p);
  }
}

If you still don't like this, other options are:

depending on what you need, both can use the UserPermissionService singleton from above

WriteEatSleepRepeat
  • 3,083
  • 3
  • 33
  • 56
  • I know I can inject it that way, but I would like it to be available everywhere automatically, like the value converters are. We also considered using a value converter, but that would give us less flexibility than using a method like in my example. Our initial approach was creating a customised version of Aurelia's `if` attribute. That worked until the latest version of Aurelia. It seems that you can no longer have multiple attributes that are a `@templateController` on the same element. – dabide Mar 09 '16 at 12:14
  • could you please detail a bit why value converter give you less flexibility? no matter which way you hide the HTML element (converter, attribute, etc), you still need something like a service which is aware of current user and checks permission. I see element hiding and checking for permission separate responsibilities. Instead of hiding, in other parts of your app, you will might want to represent user permission in a different way, so you will still need a shared logic for user permission – WriteEatSleepRepeat Mar 09 '16 at 12:26
  • 2
    We're giving this a go over here: https://github.com/SpoonX/aurelia-permissions/wiki/RFC:-Permissions. It's not done yet, but perhaps you would like to help, seeing how you seem to share the same interest. You can find us over at [gitter](https://gitter.im/SpoonX/Dev) – Wesley Overdijk Mar 09 '16 at 12:50
-1

Add a .js file in your folder, with export function ex: utility.js

export function hasPermission(permission) {
     return true/false;
 };

import the function in view-model

import {hasPermission} from 'utility';
export class MyClass{
   constructor(){
         this.hasPermission = hasPermission;
        }
 }

view.html

 <div if.bind="foo != bar && hasPermission('SOME_PERMISSION')"></div>