Angular router. How to navigate to current URL but with different parameters? - javascript

I have a Angular 5 project where users navigate to routes like this when clicking on an item.
my_domain/{account_id}/item/{item_id}/open/
my_domain/{account_id}/item/{item_id}/closed/
my_domain/{account_id}/item/{item_id}/snoozed/
Users should be able to change the account_id or item_id. So I want to be able to reload the page only changing the parametes (the ids). How can I achieve this ?

Angular 8
in .component.ts
You can use current url and put param to navigate array
this.router.navigate([this.router.url, 'open']);
or in .component.html
You can use dot as part of url "./youparam" - in this case "./" == current url
< a [routerLink]="['./open']">open</a>

Simple:
import { Router } from '#angular/router';
...
export class YourComponent{
constructor(public router: Router) {
}
...
myRouteMethod(accountId, itemId, endpointUrl){
// Use String literals
this.router.navigate([`/${accountId}/item/${itemId}/${endpointUrl}/`]);
}
}
On your HTML you can have:
<div class="wrap">
<div (click)="myRouteMethod(accountIdSomehow, itemIdSomeHow, 'open')">
open </div>
<div (click)="myRouteMethod(accountIdSomehow, itemIdSomeHow, 'close')"> close </div>
<div (click)="myRouteMethod(accountIdSomehow, itemIdSomeHow, 'other')"> other </div>
</div>
It would be useful to know how you're getting accountId and itemId.
Reusable functions will help out, always think of parameters instead of repetition, the trick is adjusting your templates to work dynamically with your component.

Related

(Nuxt) Vue component doesn't show up until page refresh

I'm storing nav items in my Vuex store and iterating over them for conditional output, in the form of a Vue/Bulma component, as follows:
<b-navbar-item
v-for='(obj, token) in $store.state.nav'
v-if='privatePage'
class=nav-link
tag=NuxtLink
:to=token
:key=token
>
{{obj.text}}
</b-navbar-item>
As shown, it should be output only if the component's privatePage data item resolves to true, which it does:
export default {
data: ctx => ({
privatePage: ctx.$store.state.privateRoutes.includes(ctx.$route.name)
})
}
The problem I have is when I run the dev server (with ssr: false) the component doesn't show up initially when I navigate to the page via a NuxtLink tag. If I navigate to the page manually, or refresh it, the component shows.
I've seen this before in Nuxt and am not sure what causes it. Does anyone know?
recommendation :
use mapState and other vuex mapping helper to have more readable code :).
dont use v-for and v-if at the same element
use "nuxt-link" for your tag
use / for to (if your addresses dont have trailing slash)
<template v-if='privatePage'>
<b-navbar-item
v-for='(obj, token) in nav'
class=nav-link
tag="nuxt-link"
:to="token" Or "`/${token}`"
:key="token"
>
{{obj.text}}
</b-navbar-item>
</template>
and in your script :
<script>
import {mapState} from 'vuex'
export default{
data(){
return {
privatePage: false
}
},
computed:{
...mapState(['privateRoutes','nav'])
},
mounted(){
// it's better to use name as a query or params to the $route
this.privatePage = this.privateRoutes.includes(this.$route.name)
}
}
</script>
and finally if it couldn't have help you , I suggest to inspect your page via dev tools and see what is the rendered component in html. it should be an <a> tag with href property. In addition, I think you can add the link address (that work with refresh and not by nuxt link) to your question, because maybe the created href is not true in navbar-item.
NOTE: token is index of nav array . so your url with be for example yourSite.com/1.so it's what you want?
This question has been answered here: https://stackoverflow.com/a/72500720/12747502
In addition, the solution to my problem was a commented part of my HTML that was outside the wrapper div.
Example:
<template>
<!-- <div>THIS CREATES THE PROBLEM</div> -->
<div id='wrapper'> main content here </div>
</template>
Correct way:
<template>
<div id='wrapper'>
<!-- <div>THIS CREATES THE PROBLEM</div> -->
main content here
</div>
</template>

how to use routerLink instead of href in anchor tag in 'innerHTML' in angular2+?

In angular 2+
If I'm using href to redirect then it reloads the whole
page.
In .ts
this.htmlText = 'The validation window for Innovator Mind nominations is open now. Last date to review is 2020-Jan-25';
in HTML,
<div [innerHTML]="htmlText "></div>
If I'm using routerlink to redirect then routerlink does not
get render in html.
In .ts
this.htmlText = 'The validation window for <a routerLink=\"http://localhost/nomination/">Innovator Mind</a> nominations is open now. Last date to review is 2020-Jan-25';
in HTML,
<div [innerHTML]="htmlText"></div>
So how to achieve the route the page without reloading the page?
add in constructor.
private router: Router
Use click event for change url by ts ->
.ts:
html='<a value="myRoute">link</a>';
changeRoute(value){
let myRoute=value.target.attributes.value.value;
if(myRoute){
this.router.navigate([ myRoute ]);
}
}
.html :
<div (click)='changeRoute($event)' [innerHTML]="html"> </div>

Include component from parent app in component contained in node_modules directory

I am working on Vue app that incorporates Vue Bootstrap Calendar, and I would like to be able to override the content of the day cell (handled by the Day.vue component) to add my own custom content inside. My thought was initially to modify the Day component to include <slot></slot> tags and pass in the custom content that way.
The problem has to do with accessing the Day component. To include the calendar in your app, you include the Calendar.vue component, which includes Week.vue, which in turn includes Day.vue. As I understand slots, I have to have the child component (Day.vue in this case) included in the component where I'm passing the data, which means it would need to be included in my own component.
If this is not possible, my other thought is to perhaps modify the library by adding another configuration prop (something like dayCustomContent) to the Calendar.vue that indicates that the Day cell content is custom content, pass that in to Calendar.vue, and then down to Day.vue, and then in the Day.vue template, have a v-if conditional based on this prop that either displays the custom content or the default cell content, something like:
<template>
<div class="day-cell" v-if="dayCustomContent">
...my custom content here...
</div>
<div class="day-cell" v-else>
...default events from my.events goes here...
</div>
</template>
I would probably then need to define a custom component to render whatever custom content I want to display, and somehow include that component within Day.vue.
So to sum up, my questions are these:
1) Is there a way to do what I need with slots?
2) For my second option, am I going down the right path? I'm open to suggestions.
UPDATE: I was able to get this done by adding a boolean customDayContent prop in Calendar.vue like so and passing it down to Week.vue and then to Day.vue:
<template>
...
<div class="dates" ref="dates">
<Week
v-for="(week, index) in Weeks"
:firstDay="firstDay"
:key="week + index"
:week="week"
:canAddEvent="canAddEvent"
:canDeleteEvent="canDeleteEvent"
:customDayContent="customDayContent"
:displayWeekNumber="displayWeekNumber"
#eventAdded="eventAdded"
#eventDeleted="eventDeleted"
></Week>
</div>
...
</template>
<script>
export default {
...
props: {
...
customDayContent: {
type: Boolean,
default: false
}
},
}
</script>
and then in Day.vue, do like I had suggested with v-if:
<template>
<div class="day-cell" v-if="customDayContent">
<custom-day></custom-day>
</div>
<div
class="day-cell"
:class="{'today' : day.isToday, 'current-month' : day.isCurrentMonth, 'weekend': day.isWeekEnd, 'selected-day':isDaySelected}"
#click="showDayOptions"
v-else
>
... existing code goes here...
</div>
</template>
The last part is referencing the CustomDay.vue component referenced in my v-if block. I want the user to be able to define the content of their own custom CustomDay.vue template in their own parent app. However, I'm having trouble trying to figure out how to do that. Following the pattern of including components already in this component, I added this in the components section of Day.vue:
CustomDay: require("../../../../src/Components/CustomDay.vue").default
? require("../../../../src/Components/CustomDay.vue").default
: require("../../../../src/Components/CustomDay.vue")
However, no matter what I try along these lines, I get an error that the relative module was not found. On top of that, I need to add it to the componentsarray only if customDayContent is true. What is the best way to do that? In a watcher or computer property, perhaps? Or another way?

Two different layouts in aurelia app

I'd like to use two separate layouts for my aurelia app. Difference between them is that one doesn't have a sidebar. Currently I'm using one layout file defined as below:
<template>
<div class="container">
<router-view></router-view>
</div>
</template>
If an active route needs this sidebar to appear I'm just putting it into its view.
What I'd like to achieve is to add another layout that would have this sidebar by default:
<template>
<require from="../common/elements/sidemenu/sidemenu"></require>
<div class="container">
<sidemenu></sidemenu>
<router-view></router-view>
</div>
</template>
So the question is - how to do this? Is it even possible with an aurelia app to have multiple layouts (or master pages, however you call those)?
Use aurelia.setRoot()
You can manually set up your application by specifying a script with configure instructions in your index.html. Typically, this is set to main.
index.html
<body aurelia-app="main">
In this script you can specify a root view model using aurelia.setRoot('root'). If no argument is provided, the convention is to use 'app'.
main.js
aurelia.start().then(() => aurelia.setRoot());
However, you can inject the aurelia object anywhere in your application, and call the setRoot function at any time to load a different root view model.
home.js
#inject(aurelia)
export class HomeViewModel {
constructor(aurelia) {
this.aurelia = aurelia;
}
doStuff() {
this.aurelia.setRoot('withSidebar');
}
}
One common use case for this is having a login page, and I've created a complete template for this use case that you can review, clone, or fork here: http://davismj.me/portfolio/sentry/

UI-Router default view inside div

Say I have index.html with:
<div ui-view="viewA">
// content
</div>
Is it posible to put content inside div that will serve to me as default route? So without including or anything else, just need to put some markup directly in that div.
There is a working plunker
That is possible, and really pretty easy. So, let's have this inside of index.html
<div ui-view="">
this is the content of ui-view,
which serves as a template for a default state
</div>
And this could be the default state and otherwise
$urlRouterProvider.otherwise('/default');
// States
$stateProvider
.state('default', {
url: "/default",
})
Check it here

Categories

Resources