Angular <a href> links - odd behaviour - angularjs

Folks I have real odd situation that doesn't seem to make sense to me at all. Here's my setup:
<html ng-app="mainApp">
<head>blah</head>
<body>
<header ng-controller="headerCntrl">
Profile
</header>
<blah>
<main ng-view></main>
<footer />
</body></html>
The header has it's own controller, then I use ngRoute to define various paths, including the profile:
.when('/profile', {
templateUrl: 'views/profile.html',
controller: 'profileController'
})
For some reason, clicking in the a href link in the header does nothing. No error, no activity. It does show the correct URL when you hover over the link, and, right-clicking and opening in new tab DOES work just fine.
Why does a normal left click not work? Bearing in mind that either:
Typing that route in directly into address bar &
Right click - open in new window
both work, what's stopping angular from loading that view into the div?
Any help much appreciated!

I think problem is that you do not specify base url. Try it.

Related

how to switch ng-view to normal page

See image
=>Layout1 master page which include ng-view in that i used angular routing.
=>Layout2 login.cshml page when I tried to call login page
http://localhost:1395/admin/home/Login
this login page included in ng-view which i donot want
its total different page Login.cshtml
I called this page like
Log out
when I tried url directly in address bar like http://localhost:1395/admin/home/Login
it works fine see image
but i tried from master panel to login page it shows wrong see first image
example code
master.cshtml
<html>
<body>
<div>Layout 1</div>
<div ng-view></div>
</body>
</html>
contact.html
<div ng-controller="contactcontroller">
Contact Page
</div>
help.html
<div ng-controller="helpcontroller">
Help Page
</div>
routing code
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/admin/home/contact", {
templateUrl : "contact.html",
controller: "contactcontroller"
})
.when("/admin/home/help", {
templateUrl : "help.html",
controller: "helpcontroller"
})
});
Login.cshtml
<html>
<body>
<div>Layout 2</div>
///Login code
</body>
</html>
when I call this url admin/home/help and admin/home/contact pages included in ng-view but when I call admin/home/login i donot want this include in ng-view it is separate header and footer . I want call as separate page
Thanks in advance
It is hard to understand this, but I'll take a shot at answering the question.
Your problem is probably unrelated to angularjs, what it seems to me is, that you're probably using ASP.NET MVC and your Login action is rendered inside the master layout. Basically you need to render the page without the template. See this question and answers there: Razor View Without Layout
I will also point out that angular is used for single page applications and it is hard to mix angular and ASP.NET MVC routing. You should probably decide which routing you will use. Sure, you can use .NET and initialize angular in every page, but I don't recommend this. If you can, build all your pages in angular and then then use ASP.NET Web API as a back-end.
Also you don't need to use ng-controller attribute when you use routing and specify controller.

AngularJS show login/logout in menu based on user status

I am making a simple angularJS application and pretty new to it. I have a menu like this
home login
I want the login to change to logout if the user has successfully loggin in. I have implemented the login (psuedo implenation), the probem I am facing is, my menu is at the top out out '
I looked at this question AngularJs, change menu item whether user is connected or not but I could not get my problem solved with it.
How do I fix this? My controller for home looks like this
scotchApp.controller('mainController', function($scope, user) {
// create a message to display in our view
$scope.isUserLoggedIn = user.getSession();
$scope.message = 'Everyone come and see how good I look!' + user.getSession();
$scope.submit = function(){
alert('Thank you. Request is sent successfully');
$('#SupportModal').modal('hide');
};
});
where user is FactoryService. That part is working fine. Any help is appreciated.
If I show {{isUserLoggedIn}} value next to menu it always show false, which is the problem. But if I put that in home.html, it show correct value. The problem is I can't build the logic with {{isUserLoggedIn}} in the menu.
I would recommend you to use ui-router.
It provide nested views and will help you a lot with this issue.
Here is a quick example(in plunker) of how to use it in your case (really simplified) :
Here is how your states should look :
$stateProvider
.state('app', {
templateUrl: 'head.html',
controller: 'HeadCtrl',
})
.state('app.feature1', {
url:'/feature1',
templateUrl: 'feature1.html',
controller:'FeatureCtrl'
})
And your differents HTML files :
Index.html (just showing the body part) :
<body ng-app="testApp">
<ui-view></ui-view>
</body>
Head.html :
<div>
<div class="header">
You are currently <span ng-show="user.connected">connected</span><span ng-show="!user.connected">disconnected</span>
</div>
<ui-view></ui-view>
</div>
feature1.html
<div class="page">
<div>
I am Bill <button ng-click="connect()">Connect as Bill</button>
</div>
<div>
I am Steve <button ng-click="connect(1)">Connect as Steve</button>
</div>
<div>
<button ng-click="disconnect()">Disconnect</button>
</div>
</div>
What you need to understand is that if you reach the "/feature1" url, you will be in state app and its substate feature1 (state app.feature1)
The first ui-view will be filed by app state's template. The ui-view in the template will be filed by feature1 state's template.
I know this is a bit unclear, but try to follow a "gettting started" guide and this exemple should help you a lot.
Hope it helped

AngularJS Ui-Router nested views not working with html5mode

I'm using AngularJS with ui-router and I have a problem with nested views while using Html5Mode. This problem only happens with html5, if I'm not using it, everything works fine. I tried to work with base <base href="/"> but didn't work as well.
Also, the problem only happens within nested views, on the main ui-view it's ok.
This is the code I'm using:
index.html
<div>
<ul>
<li ui-sref="menu">Menu</li>
<li ui-sref="user">User</li>
<li ui-sref="contact">Contact</li>
</ul>
<div ui-view autoscroll="false"></div>
</div>
child template.html
<div class="container">
<div>
<ul>
<li ui-sref="user.data">My Info</li>
<li ui-sref="user.order">My Order</li>
<li ui-sref="user.budget">My Budget</li>
</ul>
</div>
<div ui-view></div>
</div>
app.js
.state("user", {
url: "/User",
templateUrl: "content/user.html",
controller: "UserCtrl"
})
.state('user.data', {
url:"/MyData",
templateUrl: "content/user/user_data.html",
controller: 'UserCtrl'
})
If I use the html5 WITH `, i can navigate, but when i refresh the page, I get errors like this:
Resource interpreted as Stylesheet but transferred with MIME type text/html
And if I use WITHOUT <base href="/" /> then it doesn't work at all. But again, only for the child ui-view, the parent view is still working.
I haven't got such problem until now, so my knowledge is limiting, but i've heard a few things that can help you. As this ui.router tutorial says:
HTML5 Mode
The UI Router framework gives you ultimate control over the URLs
generated for your site by allowing you to enable HTML5 mode. When
enabled, this mode does not generate hash (#) locations, but uses the
HTML5 history API to generate clean URLs. The only caveat to this
approach is that you must build your application to work under each
generated path, rather than just at the root, which is customary in
most single-page applications.
I hope this helps! Cheers.

Updating url on transition from child to parent state in UI router

I have an Angular (1.2.1) app running UI-router (0.2.13), and the following state structure:
$stateProvider.state('home', {
template: "<div home></div>",
url: '/'
}).state('home.geo', {
url:'/geo/{geo}'
}
Transitioning from parent to child or between children with different {geo} parameter values works as expected. Transitioning from child to parent works - i.e. the contents of the template and $state.current change as expected - but the URL does not update in the browser.
To be clear, an example: I'm in /geo/california and I click a button with ui-sref='home'. I've confirmed that the correct href='#/' has been placed on the button, and clicking it causes the $state to transition back to the home state, but /geo/california remains in my address bar.
What am I missing here?
Update in respose to #UlukBiy's comment: No, home does not have a ui-view in its template. The ui-view is in the template of it's parent: The overall structure is:
<body>
<div app-nav></div>
<div ui-view></div>
</body>
So the home directive gets inserted into the ui-view, but it contains no ui-views of its own. Is that my problem? I'm new to UI-router, and assumed there was some low-level misunderstanding about the role of states vs. directives when I posted this. If so, please help me correct it.
This scenario should be working. There is a working example (click the blue button right-top to run example in separate window, showing the address bar)
I updated your state def a bit:
$stateProvider
.state('home', {
url: "/",
template: 'Home view <hr /> Geo view: <div ui-view></div>',
})
.state('home.geo', {
url:'^/geo/{geo}',
templateUrl: 'tpl.html',
})
All these links do work as expected:
<a href="#/home">
<a href="#/geo/california">
<a href="#/geo/czechia">
<a ui-sref="home">
<a ui-sref="home.geo({geo:'california'})">
<a ui-sref="home.geo({geo:'czech'})">
So, the most important change here is that for a child state we should use this url:
url:'^/geo/{geo}',
instead of the url:'/geo/{geo}'. Check the doc:
Absolute Routes (^)
If you want to have absolute url matching, then you need to prefix your url string with a special symbol '^'.
Check the working example here

using ng-view for hightly dynamic content?

I'm working on a website that allows you to search for different products, for example laptops. This is my index div:
<div class="content" id="main">
<div id="search-wrap">
<div id="logo"><h1>seach</h1></div>
<form id="search">
<input type="text" placeholder="Search " autofocus ng-model="query"/>
</form>
<div style="border: solid 1px blue" ng-show="query">
<ul ng-repeat="x in [] | range:10">
{{ query }}
</ul>
</div>
</div>
I have not yet implemented angular js on this but I'm thinking about how to do it. I'm not sure how to approach this, since its a complex site. Once a user searches for something, they will get results from a product. Will i have to create a different ng-view?
I'm just going by something i read online:
A page gets one ng-view. Assuming you have a single page application, this means you get one view. Use it wisely. Give some thought to what should be in the view. Is this your main content window or is this more of a navigation? Is the actual content (HTML) of this section highly dynamic? These are important decisions to make early in the development of your application if you have more than one distinct content area on your page.
Sorry if my question doesn't make sense, just not sure what to ask. Any tips will help.
thanks
You better try using ng-view and you would get more idea how it works.
There can be one ng-view in a page and it is tightly integrated with the url. When you change urls in browser, effective you are loading a different view into the ng-view area. These are configured using the $routeProvider.
ng-view is like the central content theme\area. Other views including sub-views for the main view and left nav, top nav footer is loaded using ng-include directive which has capability to compile and load any html chunk from server or locally.
For complex routing needs please have a look at ui-router which supports nested views.
For complex view you can try something like this
$stateProvider
.state('login', {
url: '/login',
controller: 'LoginController',
templateUrl: 'login.tpl.html',
access: 0
})
.state('multiple view', {
url: '/main',
access: 1,
views: {
'#': {
templateUrl: 'view1.tpl.html',
controller: 'view1Controller'
},
'page#dashboard': {
templateUrl: 'page.tpl.html',
controller: 'pageController'
}
}
})
More Info

Resources