Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember.js dynamic components

I have two Models Admin and User My application template is as follow

//application.hbs
{{outlet}}
{{header-nav}}

What I want to do (if it is possible) to make {{header-nav}} customizable, I explain : If the admin authenticate I want to render the component {{admin-header}} in the case the user authenticate it should render {{user-header}}. How can I build what to render in application.hbs dynamically ?

like image 676
Grimmy Avatar asked Jun 16 '15 08:06

Grimmy


2 Answers

You may use {{component}} helper, but you need to have component name determined first, so, in your controller:

nameForComponent: Ember.computed('user.isAdmin', function()  {
// if admin return admin-header else user-header
})

Then, in your template:

{{component nameForComponent}} 

It was designed and introduced short time ago for such use cases.

You can also go more fancy:

{{component (if user.isAdmin 'admin-header' 'user-header') }} 
like image 123
Daniel Kmak Avatar answered Oct 21 '22 11:10

Daniel Kmak


You could define isAdmin computed property in Application Controller:

// application controller 
isAdmin: Ember.computed(function() {
  // your logic here
})

// application template
{{#if isAdmin}}
  {{admin-header}}
{{else}}
  {{user-admin}}
{{/if}}

or you could wrap it as header-nav component with isAdmin property, so:

// application template
{{header-nav isAdmin=isAdmin}}

UPDATE (Details with ember-simple-auth for @Grimmy)

1) Inject currentUser into session (for example, https://stackoverflow.com/a/30894082/4950029)

2) Resolve currentUser in beforeModel hook and set currentUser controller property:

//route
beforeModel: function() {
  var self = this;
  this.session.get('currentUser').then(function(user) {
    self.controllerFor( self.routeName ).set('currentUser', user);
  },function() {
    self.controllerFor( self.routeName ).set('currentUser', null);
  });
}

//controller
isAdmin: Ember.computed('currentUser.role', function() {
  return (this.get('currentUser.role') === 'admin');
}),

//template
{{#if isAdmin}}
  {{admin-header}}
{{else}}
  {{user-admin}}
{{/if}}

or as answered above

//controller
roleBasedComponentName: Ember.computed('currentUser.role', function() {
  return ((this.get('currentUser.role') === 'admin') ? 'admin-header' : 'user-header');
})

//template
{{component roleBasedComponentName user=currentUser}}
like image 3
artych Avatar answered Oct 21 '22 10:10

artych