whole page navigation angular 4 - javascript

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)

Related

use same component with same props name in on page not works vuecli

Well. i have a component called Logo and i am using it in nearly every views and even in other components. Logo component takes only 1 props: "size" and i use javascript to mack it responsive depend on its font size but => for example i have a landing:
in landing i have component renderd in landing: navbar that contains a "logo component" inside OF HIM. and same time i use logo component in my landing view as well:
LOGO COMPONENT
<template lang="html">
<div class="logoCon">
<a class="logo">Some name for Logo</a>
</div>
</template>
<script>
export default{
props: ['size'],
name: 'Logo',
methods: {
logoSizing(size){
// java script code for make the sizing right.
}
},
created(){
// calling logoSizing function.
this.logoSizing(this.size);
// for adding the font size.
document.querySelector(".logo").style.fontSize = (this.size + "px");
}
}
</script>
NAVBAR COMPONENT
<template lang="html">
<div class="navbarCon">
//some code for navbar. and inside the navbar we have logo component:
<logo :size="logoSize" />
</div>
</template>
<script>
export default{
name: 'Navbar',
data: () => ({
logoSize: "20"
})
}
</script>
and the last one LANDING COMPONENT
<template lang="html">
<div class="navbarCon">
// navbar component
<navbar />
// we have logo component:
<logo :size="logoSize" />
</div>
</template>
<script>
export default{
name: 'Landing',
data: () => ({
logoSize: "400"
}),
components: {
navbar,
logo
}
}
</script>
so now if i run the code the "logoSize" varible dont work for each in seperate ways and get only one of the logo components, mostly just the navbar and the logo component in landing it gets no style at all from my java script.
=>how can i use the logo component multiple times in one page and works for each in seprate ways
THIS ISSUE IS NOT ONLY FOR MY LOGO COMPONENT ALL OF MY COMPONENTS ARE HAVE THE SAME PROBLME PLEASE HELP ME SOLVE IT.... I WANT TO CRY
So considering that your logoSizing(size) doesn't change the size value (because you souldn't mutate props because when you do, you change it in the parent component as well and may lead to inconsistent changes), I would say that maybe your components are being renderes with the same id (which sound kinda weird).
To solve that "problem", (and again this shouldn't happen unless you're forcing it somehow) give to the components different key's like
<logo :size="400" :key="navbarLogo"/>
<logo :size="300" :key="appbarLogo"/>
This forces your components to have a different ID in DOM.
But a codepen would be really handy

Angular navigation issue

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');
}

In VueJS, how do I use load in a view based on what is populated in my JS?

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

Creating Tabs and calling sub-components with Bulma and Angular 5

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.

Partial accordion-style animation on Angular component with various templates

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.

Categories