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
Related
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 am building app using laravel and vue. I have navbar, currently it looks like:
<template>
<nav class="navbar">
<p>{{msg}}</p>
</nav>
</template>
And I use it like here:
<body class="">
<div id="app">
<div class="">
<navbar></navbar>
#yield('content')
</div>
</div>
</body>
In yield I am loading another components, so I have navbar and another component together. Now I want to override that {{msg}} variable from navbar in another components. In every component that variable will be diferent.
I do not know how to override it in components and from {{msg}} do some text. Can you help me? (That code above is all what I have)
If you want to use msg in other components, then you need to use prop
Use like:
props: ['msg'],
Then, you need to bind it like:
<component-name :msg="msg"></component-name>
In your component, you can take it like:
<template>{{ msg }}</template>
Hope you understand!
Components can be communicate with props. You can transfer the data to another components and you can use if statement.
https://v2.vuejs.org/v2/guide/components.html#Props
Please bear with me, this question is very crude. I'm new to Ember js, and have got a lotta confusion between views controllers templates routes. I have this basic requirement, to have a menu on the left, with item users, organizations. and a div in the center, As of now, when i click users, i have given a link to /users route. for organizations /organizations route, which is a different template. I want to display them in the centered div. Not sure how to do that. I think it has got something to do with child views, but find myself numb in beginning. I just need help in the workflow of how to achieve this.
EDIT:
Here is the basic code, I have this page called home. Template home.hbs:
<ul class="nav nav-list">
<li>
{{#link-to 'users'}} Users{{/link-to}}
</li>
<li>
{{#link-to 'organizations'}} Organizations {{/link-to}}
</li>
</ul>
<div class="summary-width span10" id="home-container">
</div>
Similarly there is users.hbs and organization.hbs.
When a user clicks on users link, i want the users template to be displayed in home-container div. organizations template otherwise.
Generally you do what you are describing with routes. This is your application.hbs ie the template associated with the application route and controller.
<ul class="nav nav-list">
<li>
{{#link-to 'users'}} Users{{/link-to}}
</li>
<li>
{{#link-to 'organizations'}} Organizations {{/link-to}}
</li>
</ul>
<div class="summary-width span10" id="home-container">
{{outlet}}
</div>
you would then have a router:
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('organizations');
this.route('users');
});
export default Router;
{{link-to 'users'}} will enter the users route, call all the hooks, create the controller if it doesn't already exist, set the model on the controller, and render the users.hbs template into the application template's outlet. The home.hbs you are describing should be renamed to index.hbs because by default Ember renders your index.hbs template into the outlet when / is accessed (or whatever your base url is). Sure, its possible to make a different template be the default but that involves more code so just change your home.hbs to index.hbs
Edit:
add this to your router:
this.resource('home', function(){
this.route('organizations');
this.route('users');
});
if those routes are truly nested below your home route. Your link to's would need to change to {{#link-to 'home.organizations'}}
If you don't nest like this, then {{#link-to 'users'}} will render the users.hbs file into the application's outlet. That's just how Ember and the router work.
If you can't nest for some reason, then change the link-to to actions, make the {{outlet}} a named outlet like {{outlet 'named'}} and in your routes/home.js actions hash, make actions that this.renderTemplate() into the named outlet. Look at the api for exactly how to do this
I have an AngularJs app with start up page as index.html, by default the projects view will be displayed and on top of the page I am showing a icon to show the todo items (for the logged-in user) which I am using bootstrap's data-toggle dropdown. The issue is whenever I click the todo link the partial view (todo.html) is not showing. BTW, I am new to the angular world so please forgive me if there is anything silly. Please see the code below:
Index.html
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head></head>
<body>
<a data-toggle="dropdown" class="dropdown-toggle" ui-sref=".todo">
<i class="icon-tasks"></i>
<span class="badge badge-grey">4</span>
</a>
<div ng-view></div>
</body>
app.js
// For any unmatched url, redirect to /projects
$urlRouterProvider.otherwise("/projects");
//
// Now set up the states
$stateProvider
.state('projects', {
url: "/projects",
templateUrl: "/app/views/projects/projects.html",
controller: "projectController"
})
.state('projects.todo', {
url: "/todo",
templateUrl: "/app/views/todo/todo.html"
});
First of all replace ng-view with ui-view in the root template, cause it seems you want to use ui-router instead of ng-router.
Wrap the content of your template files with div of ui-view as a parent element.
/app/views/projects/projects.html
/app/views/todo/todo.html
<div ui-view>
... previously defined content ...
</div>
Let's say your view was
<div class="container">
<div class="page-header">
<h1>Title: {{title}}</h1>
</div>
</div
you need to add ui-view to the div
<div class="container" ui-view>
<div class="page-header">
<h1>Title: {{title}}</h1>
</div>
</div
or wrap your view with div containing ui-view descriptor in case your vie contains several tags.
I cannot show you an example since you did not provide content of view files.
/app/views/projects/projects.html
/app/views/todo/todo.html
The issue is that after fist template applying angular does not see the place to put new template anymore.
ui-router isn't really supposed to be used in this way. To integrate bootstrap with angular you want to look at UI Bootstrap - http://angular-ui.github.io/bootstrap/
Then to achieve your drop down, look at their basic examples. If you want to use separate view files to define your drop down content, you can use <div ng-include="'mycontent.html'"></div>.
ui-router is useful if you have a complex view hierarchy, where you are for example, looking for dynamic loading of children, while keeping parent states static.
In ui-router you defined all of this in the $stateProvider, so there you should define that you have a view that has another view belonging to it, example:
<!-- In index.html the main view that will have all the page views-->
<div id="main" ui-view="main"></div>
<!-- In todo.html with a partial with the dropdown code in dropdown.html -->
<h1> This is a nice todo drop down </h1>
<div id="todoDropDown" ui-view="todoDropDown"></div>
//In your app file
.state('projects.todo', {
url: '/todo',
views: {
'main#': {
templateUrl: '/app/views/todo/todo.html',
controller: 'TodoCtrl'
},
'todoDropDown#projects.todo': {
templateUrl: '/app/views/partials/dropdown.html'
}
}
})
"todoDropDown#projects.todo" This does the magic, it tells that this view has another view inside. And you can add controller to it and all other options you have in ui-router. In this way you can break up as much as possible reusable parts.