How to use one template in multiple Ironrouter route? - templates

I want to display the template named "home" with the route "/" and "/home" but with my code it doesn't work
/** Iron router config file **/
Router.configure({
layoutTemplate: 'layout',
notFoundTemplate: '404',
loadingTemplate: 'loading',
fastRender: true,
});
// Home
Router.route('/', {
name: 'home',
waitOn: function() {
return [
Meteor.subscribe('infosContainers'),
Meteor.subscribe('infosMachines'),
Meteor.subscribe('alertes'),
];
},
fastRender: true,
});
Router.route('/home', {
name: 'home',
waitOn: function() {
return [
Meteor.subscribe('infosContainers'),
Meteor.subscribe('infosMachines'),
Meteor.subscribe('alertes'),
];
},
fastRender: true,
});
It doesn't like the fact that the template "home" is in 2 routes (because if I set name: sokasok in the second one it works )
Could you help me ?

'name' is not for the template render, it's the name of the route. What you need to do is call this.render('home') in action of the route.
Router.route('/home', {
waitOn: function() {
return [
Meteor.subscribe('infosContainers'),
Meteor.subscribe('infosMachines'),
Meteor.subscribe('alertes'),
];
},
action: function(){
this.render('home');
}
fastRender: true,
});

Related

Vue router permission based on User Role from Django Rest Framework

I have Django and Vue project and I need to add permissions in the Vue router based on user role.
I managed to do this in the template by accessing the user data from my user API.
<li class="nav-item active mx-1 mb-1">
<router-link
v-if="user_data.role != 2"
:to="{ name: 'activities' }"
class="btn btn-sm btn-success"
>Activities
</router-link>
</li>
<script>
import { apiService } from "#/common/api.service.js";
export default {
name: "NavbarComponent",
data() {
return {
user_data: {},
}
},
methods: {
setRequestUser() {
this.requestUser = window.localStorage.getItem("username");
},
getUserData() {
// get the details of a question instance from the REST API and call setPageTitle
let endpoint = `/api/user/`;
apiService(endpoint)
.then(data => {
this.user_data = data;
})
},
},
computed: {
isQuestionAuthor() {
return this.requestUser === 'admin_user';
},
isUser() {
return this.requestUser;
},
},
created() {
this.setRequestUser()
this.getUserData()
}
};
</script>
The user doesn't see the button but can still access the pages if enter the path directly in URL.
I can't find a workaround to get the same user data from user API and use it to manage route permissions based on user.role
My router.js looks like this:
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "home",
component: Home
},
{
path: "/activities",
name: "activities",
component: Activities
},
{
path: "/add-activity/:slug?",
name: "activity-editor",
component: ActivityEditor,
props: true
},
{
path: "/activities/:slug",
name: "activity",
component: Activity,
props: true
},
{
path: "/cto-entries",
name: "cto-entries",
component: CTOEntries,
},
{
path: "/add-cto-entry/:slug?",
name: "cto-editor",
component: CTOeditor,
props: true
},
{
path: "/question/:slug",
name: "question",
component: Question,
props: true
},
{
path: "/ask/:slug?",
name: "question-editor",
component: QuestionEditor,
props: true
},
{
path: "/answer/:id",
name: "answer-editor",
component: AnswerEditor,
props: true
},
{
path: "*",
name: "page-not-found",
component: NotFound
}
];
const router = new VueRouter({
mode: "history",
//base: process.env.BASE_URL,
routes
});
export default router;
Is there any way to do this in vue router or there is a better way?
I am new to Vue.js, please help :)
Solved this by using beforeEnter and fetching user role from API...
import { apiService } from "#/common/api.service.js";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "home",
component: Home
},
{
path: "/activities",
name: "activities",
component: Activities,
beforeEnter(to,from,next) {
var user_data = {};
let endpoint = `/api/user/`;
apiService(endpoint)
.then(data => {
user_data = data;
if(user_data.role!=2){
next();
} else {
next("/");
}
});
},
},

Accessing model properties in Controller - Ember

So, I'm trying to access my model properties in controller.
Controller:
dashobards: [
{ id: 12, name: 'test' },
{ id: 17, name: 'test2' },
];
In route I have model named dashboards
return Ember.RSVP.hash({
dashboards: this.store.findAll('dashboard'),
}).then((hash) => {
return Ember.RSVP.hash({
dashboards: hash.dashboards
});
}, self);
I wanna have result in controller like this:
dashboards: [
{ id: 12, name: 'test' },
{ id: 17, name: 'test2' },
{ id: 17, name: 'test1' },
{ id: 20, name: 'test20' },
];
In controller I am trying to access this model like this:
this.dashborads = this.get(model.dashobards)
And it's not working, is there any other way of doing that?
Another update How to access complex object which we get it from server in ember data model attibute,
Created twiddle to demonstrate
define attribute with DS.attr(),
export default Model.extend({
permissions:DS.attr()
});
route file,
model(){
return this.store.findAll('dashboard');
}
Your server response should be like,
data: [{
type: 'dashboard',
id: 1,
attributes: {
permissions: {'name':'role1','desc':'description'}
}
}]
hbs file,
{{#each model as |row| }}
Name: {{row.permissions.name}} <br/>
Desc: {{row.permissions.desc}} <br />
{{/each}}
Update:
Still I am not sure about the requirement, Your twiddle should be minimalized working twiddle for better understanding..anyway I will provide my observation,
1.
model(params) {
this.set('id', params.userID);
const self = this;
return Ember.RSVP.hash({
dashboards: this.store.findAll('dashboard'),
user: this.store.findRecord('user', params.userID)
}).then((hash) => {
return Ember.RSVP.hash({
user: hash.user,
dashboards: hash.dashboards
});
}, self);
}
The above code can be simply written like
model(params) {
this.set('id', params.userID);
return Ember.RSVP.hash({
dashboards: this.store.findAll('dashboard'),
user: this.store.findRecord('user', params.userID)
});
}
Its good to always initialize array properties inside init method. refer https://guides.emberjs.com/v2.13.0/object-model/classes-and-instances/
For removing entry from array,
this.dashboard.pushObject({ 'identifier': '', 'role': '' }); try this this.get('dashboard').pushObject({ 'identifier': '', 'role': '' });.
if possible instead of plain object you can use Ember.Object like
this.get('dashboard').pushObject(Ember.Object.create({ 'identifier': '', 'role': '' }));
For removing entry.
removeDashboard(i) {
let dashboard = Ember.get(this, 'dashboard');
Ember.set(this, 'dashboard', dashboard.removeObject(dashboard[i]));
}
The above code can be written like, since i is an index
removeDashboard(i) {
this.get('dashboard').removeAt(i)
}
Just do return this.store.findAll('dashboard'); in route model hook, and dont override setupController hook, then in hbs you should be able to access model that will represent RecordArray. you can have a look at this answer for how to work with this.

Angular2 dynamic templating

How do I use nested templates in angular2. So basically I have a base component and it's childs
- entry.component.ts
- entry.component.html
- navigation
-- sidenav.ts
-- sidenav.html
-route1
--route1.ts
--route1.html
entry.component.html should be a skeleton and the content should be generated dynamically on route changes.
Is it possible to achieve this?
Use templates with child routes.
I separate mine in public and secure routing everything through the layout then loading the routes for which ever layout is chosen.
Make sure to export the child routes and that the correct routes are called in the layout route. Also make sure you use redirectTo in each child routes file.
app.routing.ts
const APP_ROUTES: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full', },
{ path: '', component: PublicComponent, data: { title: 'Public Views' }, children: PUBLIC_ROUTES },
{ path: '', component: SecureComponent, canActivate: [Guard], data: { title: 'Secure Views' }, children: SECURE_ROUTES }
];
Then I have a layouts folder
layouts
layouts/public/public.components.ts
layouts/public/public.components.html
layouts/secure/secure.components.ts
layouts/secure/secure.components.html
child routes
/public/piublic.routes.ts
export const PUBLIC_ROUTES: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'p404', component: p404Component },
{ path: 'e500', component: e500Component },
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'home', component: HomeComponent }
];
/secure/secure.routes.ts
export const SECURE_ROUTES: Routes = [
{ path: '', redirectTo: 'overview', pathMatch: 'full' },
{ path: 'items', component: ItemsComponent },
{ path: 'overview', component: OverviewComponent },
{ path: 'profile', component: ProfileComponent },
{ path: 'reports', component: ReportsComponent }
];
Creating components to load into the template
import { Component, OnInit } from '#angular/core';
#Component({
templateUrl: './benefits.component.html',
})
export class BenefitsComponent {
constructor() { }
}
The create its html template,
/public/benefits.component.html'
Now that it is part of the public route. When someone goes to a public route it will be loaded in the chile routes. so inside your
/public/public.routes.ts file you would add it for every new route you wanted to create to load your new html page.

Meteor - alternative layout template

I have a layout template but want to apply an alternative layout template. I have created altLayout.html but how do I apply it to my route?
Router.configure({
layoutTemplate: 'layout',
notFoundTemplate: 'pageNotFound',
//waitOn: function() { return Meteor.subscribe('items'); }
});
Router.map(function() {
this.route('main', {
path: '/',
template: 'main',
notFoundtemplate: "pageNotFound",
oldBrowserTemplate: "oldBrowser",
onBeforeAction: function () {
// render the unsupported browser page if user isn't using Chrome
if(BrowserDetect.browser == "Chrome"){
layoutTemplate: 'altLayout',
this.render('oldBrowser');
this.stop();
}
},
});
});
The following works for me:
Router.route("/product/:id",
{
name: "product_page",
template: "product_page",
layoutTemplate: "product_page_layout",
data: function()
{
return {id: this.params.id}
}
});
The "product_page_layout" is where your altLayout.html template goes. Basically:
Router.map(function() {
this.route('main', {
path: '/',
template: 'main',
layoutTemplate: "altLayout",
notFoundtemplate: "pageNotFound",
oldBrowserTemplate: "oldBrowser",
onBeforeAction: function () {
// render the unsupported browser page if user isn't using Chrome
if(BrowserDetect.browser == "Chrome"){
layoutTemplate: 'altLayout',
this.render('oldBrowser');
this.stop();
}
},
});
});

controller control sencha touch 2 doesnt work

My controller seems that it doesnt work :
Controller:
Ext.define('MyApp2.controller.Details',{
extend : 'Ext.app.Controller',
config: {
refs:{
NewsContainer: 'NewsContainer'
},
control:{
'NewsContainer home list':{
itemtap: function(){
console.log("item");
}
}
}
}
});
Home :
Ext.define('MyApp2.view.Home', {
extend: 'Ext.Panel',
xtype: 'home',
requires: [
'Ext.tab.Panel',
'Ext.dataview.List',
'MyApp2.view.NewsContainer'
],
config: {
title: 'Home',
IconCls:'home',
styleHtmlCls:'details',
styleHtmlcontent:'true',
scrollable:true,
layout:'fit',
items: [
{
xtype: "list",
store: "NewsStore",
itemTpl: new Ext.XTemplate (
'<div>',
'<img src="{enclosure}" />',
'<h1>{title}</h1>',
'</div>'
),
itemCls:'news-entries'
}
]
}
});
NewsContainer:
Ext.define('MyApp2.view.NewsContainer', {
extend: 'Ext.NavigationView',
xtype: 'NewsContainer',
config: {
autoDestroy: false,
title: 'Home',
IconCls:'Home',
items: [
{
xtype:'home'
}
]
}
});
and here is my app.js:
Ext.application({
name: 'MyApp2',
requires: [
'Ext.MessageBox'
],
controller:['Details'],
models:['MyApp2.model.News'],
views: [
'Main','Home','News','NewsContainer','Details'
],
stores:['NewsStore'],
icon: {
'57': 'resources/icons/Icon.png',
'72': 'resources/icons/Icon~ipad.png',
'114': 'resources/icons/Icon#2x.png',
'144': 'resources/icons/Icon~ipad#2x.png'
},
isIconPrecomposed: true,
startupImage: {
'320x460': 'resources/startup/320x460.jpg',
'640x920': 'resources/startup/640x920.png',
'768x1004': 'resources/startup/768x1004.png',
'748x1024': 'resources/startup/748x1024.png',
'1536x2008': 'resources/startup/1536x2008.png',
'1496x2048': 'resources/startup/1496x2048.png'
},
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
// Initialize the main view
Ext.Viewport.add(Ext.create('MyApp2.view.Main'));
},
onUpdated: function() {
Ext.Msg.confirm(
"Application Update",
"This application has just successfully been updated to the latest version. Reload now?",
function(buttonId) {
if (buttonId === 'yes') {
window.location.reload();
}
}
);
}
});
Can u tell me please what's wrong with my code ?there is no error in the console , nothing's happened when i tap :(
The problem is, that the controller doesn't find the reference to the list.
There is no error message, because the itemtap event from the list is not catched.
I think this controller code is going to work:
Ext.define('MyApp2.controller.Details',{
extend : 'Ext.app.Controller',
config: {
refs:{
homeList: 'home list'
},
control:{
homeList : {
itemtap : function(list, index, item, record) {
console.log("item");
}
}
}
}
});
Adding
itemId : list in the view
and in the controller the next line :
main : 'main , it´s enough for you...
Ext.define('MyApp2.controller.Details',{
extend : 'Ext.app.Controller',
config: {
refs:{
main : 'main',
homeList: 'main list'
},
control:{
homeList : {
itemtap : function(list, index, item, record) {
console.log("item");
}
}
}
}
});