When I click the whole card it should navigate to the project detail component and then when I click the BID RECEIVED button it should navigate to the bids component but it navigates to project detail page
<div class="card" *ngFor="let data of projectdata">
<div class="card-body" routerLink="/projectdetail/{{data._id}}">
<div class="bids" routerLink='/bids/5edbd6eb3290c300179cc2f9'>{{data.totalBids}} BIDS RECEIVED</div>
</div>
</div>
Not sure it is a good practice to have nested RouterLinks, but this solution might work in your case: https://stackoverflow.com/a/53147466/12660773
Try removing the router link on the bids div and replacing it with (click)=nav() and then in your .ts file:
import {Router} from '#angular/router';
constructor(private router: Router) {}
nav() {
this.router.navigateByUrl('/bids/5edbd6eb3290c300179cc2f9');
}
Related
I am new to Vue.JS and require a little help as I am stuck with some logic.
I have been given a project to building and as I am under NDA I can only show comparative code examples.
In one View (Bars), which is brought into the viewport of the application using the router, I have a simple for loop.
<ul class="bar-listings">
<li v-for="bar in bars">
<router-link to="{bar.barPage}">
<div class="item">
<div class="item-bd">
<h2>{{ bar.barName }}</h2>
</div>
</div>
</router-link>
</li>
</ul>
Then in my JS file conatining all my data, I have this (Only one object for now)
export default [
{
barName: "The Tropicana Bar",
barPage: "views/bars/Tropicana",
}
];
The title displays correctly on Bars so the loop is pulling the data correctly.
However, I will have a .vue file for each bar, which also uses the data from my JS file. See below:
<template>
<div class="content-wrapper">
<h1>{{ getBarByIndex({ bars, index }).barName }}</h1>
</div>
</template>
<script>
import bars from "./../../data/bars";
export default {
data() {
return {
bars: bars
};
},
methods: {
getBarByIndex({ bars = [], index = 0 }) {
return bars[index] || {}
}
}
};
</script>
So what I need to solve is how do I make the <a v-bind:href=""> load the view for this bar?
What I think you can do, is to have a child component inside your component, you can leverage this by using nested routes in your router-view, additionally, you can pass props as an object to your router components, parent or child, whatever you need.
Basically, you will have a main router view, but inside your component, you will have another router-view which renders child components.
See: Nested Routes
See: Passing Props to Route components
I want to create a navigation panel with tabs, I'm using Bulma, I'll show an example from the documentation.
I'm using routing for the navigation of the project, but from my Matches component, I want to call a subcomponent from each tab.
<div class="tabs">
<ul>
<li class="is-active"><a>Upcoming</a></li>
<li><a>Past</a></li>
</ul>
</div>
Working like this:
From the matches component call a subcomponent app-upcoming and app-past
<div class="upcoming">
<app-upcoming></app-upcoming>
</div>
<div class="past">
<app-past></app-past>
</div>
Use the router-outlet to specify where to display the route components:
https://angular.io/tutorial/toh-pt5#add-routeroutlet
When you use a route component, like this from the documentation.
import { HeroesComponent } from './heroes/heroes.component';
const routes: Routes = [
{ path: 'heroes', component: HeroesComponent }
];
The component will get loaded into the router-outlet when the path matches heroes. I'd recommend reading the routing documentation and following it along.
It is super easy you just go with router. Take a look of https://angular.io/guide/router.
I'm making a production app that has a card-style layout. Every filter (date pickers, etc) and visualizers (table, chart) is wrapped inside a "Card" component. There are even two child components that inherit from this class.
So in the end, this is how a pair of cards look, so you can have an idea on what's going on:
As you can see, the cards have 3 parts:
A header
An inner component (which is put inside a ng-content)
A footer with some summary information
The requisite we currently have, is to be able to click in the chevron (that icon in the card header right), and hide just the inner component. This is the result I want to achieve:
But I'm having a problem with this, because of how I designed these cards. Look at how the card code parent class looks:
#Component({
selector: "card",
styleUrls: ["./card.css"],
template: `
<div class="col card" [#animate]="enabled">
<div class="row card-header">
{{title}}
<i (click)="switchVisibility()" class="fa fa-chevron-down icon-right"></i>
</div>
<div class="margin" [#animate2]="enabled">
<ng-content></ng-content>
</div>
`
Implementation:
<card [title]="'DATE SELECT'" class="col">
<date-picker-wrapper class="date-wrapper" [config]="config" [dateranges]="dateranges" [doubleDateRange]="false">
</date-picker-wrapper>
</card>
You probably have already spotted one of the problems here: all of the inner component is inserted in the ng-content, therefore, if I hide the component with an animation located at the Card (which is the idea, so I can inherit this method in the child card classes)... I will hide the footer too. And that's not the plan.
I guess I need to wrap inside the ng-content the upper side template, and the footer in another different template or something. But I don't know how to do it, and the guides regarding ng-template didn't seem to be very clear. Also, I'm not very sure of what's the best approach to achieve this result.
This is how a component's footer looks, in this case, the daterangepicker:
<div class="footer-component">
<hr>
<p class="footer-text">
<span style="color:#ff8716;">
{{ config?.daterange?.rangelabel ? config?.daterange?.rangelabel : "Custom" }}
</span>
|
{{ getFormattedDate(1, true) }} - {{ getFormattedDate(1, false) }}
</p>
<button class="btn btn-relocator" (click)="openDate(datemodal)">Edit</button>
</div>
One of the problems I see here, is that this footer actually requires some functionality of the component, some methods that are not global and therefore, not accessible from outside of the component.
Then, I've got a few questions:
Should I replicate this animation in all my components, inside their template? Wouldn't that be a little bit dirty? How would you populate the state of the chevron icon click to the inner component?
If there is a way of inserting two templates in the Card component, how do you think I can access the component's logic from the footer template?
Any comments regarding how I should "hide" the content? I've got an idea using "*" height as for "auto", but I'm not sure if that even works.
For hiding the , you need to use a boolean toggle variable.
In your component, declare variable as below:-
enabledContent = false;
Then try to modify your html like below:-
<div class="col card" [#animate]="enabled">
<div class="row card-header">
{{title}}
<i (click)="enabledContent=!enabledContent;switchVisibility();" class="fa fa-chevron-down icon-right"></i>
</div>
<div class="margin" [#animate2]="enabledContent">
<ng-content></ng-content>
</div>
Click on this for sample code
because I am not aware [#anumate2], in sample link it is [hidden] .
For enable a method global, you may achieve by doing below step:-
First create a service,
myservice.service.ts and inside write your function(sample code showing only):-
public getFormattedDate(1, true): any {
return result;
}
Now in your component , declare your service as below(sample code showing only):-
import { Component, OnInit,} from '#angular/core';
import { MyService} from './myservice.service';
#Component({ selector: ... templateUrl: ... styleUrls: ... })
export class MyComponent implements OnInit {
constructor(private myservice: Myservice) { }
ngOnInit() { }
}
Then in your html file, use your service method as below(sample code showing only):-
<div class="footer-component">
{{ myservice.getFormattedDate(1, true) }} - {{ myservice.getFormattedDate(1, false) }}
</div>
I tried to use variable from a service.ts inside html file, it works fine, but I haven't tested calling method from service.ts. Hope it will work. If it is ok, then you can call your service method from anywhere as services are global in angular and just need to declare in component to be used.
I'm new to angular and starting to get the hang of routing and components. However I have a question regarding:
How I can navigate to a second page (component) and display only that content and not just load component data into <router-outlet></router-outlet>.
First page component
Second page component
When I click the button I want the whole page to display the second component data only. I basically would like to know how I can do whole page navigation in Angular 4.
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { ApplyComponent } from './apply/apply.component';
import { RouterModule, Routes } from '#angular/router';
#NgModule({
declarations: [
AppComponent,
ApplyComponent
],
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: 'apply', component: ApplyComponent
}
])
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.componenter.html
<div class="container">
<br><br>
<h1 class="header center orange-text">First page</h1>
<div class="row center">
</div>
<div class="row center">
<a
routerLink="/apply"
class="btn waves-effect waves-light"
type="submit"
name="action">
Second page
</a>
</div>
<br><br>
</div>
<router-outlet></router-outlet>
apply.component (second page)
<div class="container">
<br><br>
<h1 class="header center orange-text">Second page</h1>
<div class="row center">
</div>
<div class="row center">
<a
routerLink="/"
class="btn waves-effect waves-light"
type="submit"
name="action">
Back
</a>
</div>
<br><br>
</div>
If you have any questions or need clarification don't hesitate to ask!
Thanks beforehand!
/E
In Angular, you can nest one component into another thereby keeping the parent component and then loading the child component within the parent. Components can also exist without being nested into another. Where you declare your component tags really matters.
Let's say we have site which has a navigation bar we want to show on all pages. First of all, a primary component (named app.component) which usually has the selector name <app-root></app-root> (that is if you create your angular project using the Angular cli) is inserted into the index.html, which loads the app.component when the application starts. Now, since we want to show the navbar on all pages, you can create a navbar component and place it's selector tags in the app.component.html (which is the view for app component) and also place your <router-outlet></router-outlet> . Since the app.component is the parent for all the other components, the navbar will show on every other component. Now, what if we can don't want the navbar to show on every component? Then we do the opposite, we don't place <navbar></navbar> in the root. We place it in the component where we want it to show and then every other child component will show it too. Now, every component that is placed in the app.component won't show the navbar
So in short, if you want to 'display the second component data only', make it a parent component. Hope I answered your question.
You need a route entry for / like shown in
RouterModule.forRoot([
{
path: '', component: DummyComponent, pathMatch: 'full',
path: 'apply', component: ApplyComponent
}
])
for this you need some component (like DummyComponent) that might not have any content in the view. It is used just to satisfy the router.
pathMatch: 'full' is required for routes with an empty path '' and no child routes.
your app-root html and parent component will always display; what you need is the components of your front page in its own component.
> app-component (always displays) //the parent
> child components
> Home
> About
> Products
> ...
your router can then route/display each component (using a navbar in the parent)
When I use the routerLink directives inside my #Component's template property, it works.
But we're talking about my entire sites top menu bar. But when I separate it out into my main template file (layout.html), it no longer functions.
Yeah im a huge noob to ng2, admittedly, but I'd like my menu to stay out of a javascript file and inside the main layout html. How can one accomplish this?
<body>
<base href="/" />
<div class="row menu">
<div class="container">
<ul class="u-pull-left">
<li><a [routerLink]="['/']" routerLinkActive="active">Home</a></li>
<li>Notifications</li>
<li>My Hisses</li>
</ul>
<ul class="u-pull-right">
<li><a [routerLink]="['/register']" routerLinkActive="">Register</a></li>
<li><a [routerLink]="['/login']" routerLinkActive="active">Login</a></li>
</ul>
</div>
</div>
<root></root>
<!-- End Document
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
</body>
Which vital step am I missing? Is it even possible?
Thank you!
routerLink is a directive and [routerLink]="..." is a binding to the input of a directive. None of these are supposed to work outside of an Angular2 component.
You can use a shared service that is instantiated outside of Angular2 and passed as a provider
let service = new MyService();
#NgModule({
providers: [{provide: MyService: useValue: service}],
...
})
class AppModule {}
then you can use service to communicate with some Angular2 component or service to delegate calling router.navigate(...) do do imperatively what routerLink would do.
Another way is firing events (window.dispatchEvent(...)) and listening for this events inside Angular2.
If possible I'd avoid such a setup (having router links outside Angular2 components) entirely.
You cannot do this because routerLink is special angular2 syntax that gets transpiled down to js and your template HTML is the bootstrap of the application and does not get transpiled .
Typically what you would do to accomplish a static top bar is to create a new topbar component and use it as a directive in your parent app above where you call your router outlet.
Example. In your app.component. you would import your component
Import {TopNav} from 'topnav.component '
#Component({ selector : 'my-app', template : , directives: [TopNav] })
Your topnav component would contain your routing logic