ui-route not redirecting to external page - angularjs

From a modal dialog I present a general terms link that should redirect the user to a new page.
I would like to re-use my layout skeleton (background, logo ans basic styles) for the terms page, without the content of the master page (eg. search function, navigation etc). To achieve this I try to inject into a new window the terms template inside the ui-view="main" used for the normal site content (where is loaded the content of the modal dialog, as instance), but I get the error Could not resolve 'terms' from state 'login' (login is the current state where the modal dialog is).
Below the termsPage module with the ui-router state I would like to load:
angular.module('termsPage').config(function ($stateProvider) {
$stateProvider
.state('terms', {
url: '/terms',
views: {
'main': {
controller: 'TermsCtrl as Terms',
templateUrl: '/modules/staticPages/views/termsPage.html'
}
}
});
});
My index.html file:
<!-- Other tags excluded for sake of semplicity -->
<body ng-app="myApp">
<!-- Here I inject all the content -->
<div id="wrapper" ui-view="main">
</div>
Below the app module and view, where the content of the application is correctly loaded. Also the modal dialog from which I would like to redirect to the external page is loaded here.
angular.module('app').config(function($stateProvider){
$stateProvider
.state('app', {
url: '/app',
views:{
'main' : {
controller : 'AppCtrl',
templateUrl: 'modules/app/views/app.html'
}
}
});
});
Below app.html:
<div id="container">
<div class="browser">
<div class="content" ui-view="content" style="position:relative;">
</div>
My goal would be to create a sibling of app.html, injecting in main placeholder the content of my general terms page. Inside the modal dialog controller I use $state.go for the redirection:
$state.go('terms');

In my case the problem was that I did not registered the new module ('termsPage') as dependency in my main module:
angular.module('myApp', ['login','forms','termsPage'], function($urlRouterProvider){ ...}
Now that the module is registered, I can navigate correctly to state 'terms'.
Hopefully the case above might help someone else, getting hints for his/her case.

Related

Use ui-view as the template for state inside ui-router instead of an external template

I have an app that is currently using the angular ui-router module dependency. The only aspect of the ui-router that I'm currently employing is the ability to apply/modify $stateParams to $scope and vice versa so the URL can change the way data is displayed in the controller to a user on arrival (i.e. url?param=something will filter the data by something).
I have the following in my app.config to set the state:
$stateProvider
.state('root', {
url: '/?param',
templateUrl: 'template.html',
controller: 'listController',
params: {
param: {
value: 'something',
squash: true
}
}
});
On my homepage, template.html successfully loads when the app is instantiated as such:
<div ng-app="myApp">
<div ui-view>
</div>
</div>
However, I have reached a roadblock and realize that calling the template from within templateUrl isn't going to work, as this app is being built inside another framework and therefore needs to be called from within the homepage itself to access its full capabilities.
Being a noob at AngualrJS, I was wondering if anyone can tell me what the best way is to accomplish this while still keeping the logic of $stateParams and other ui-router capabilities intact for the future.
For instance, could I just remove the templateUrl parameter from my state and call the controller directly inside the ui-view like this:
<div ng-app="myApp">
<div ui-view>
<div ng-controller="listController">
do something
</div>
</div>
</div>
I also looked into changing the entire logic from using ui-router to simply using the $location service but I'm wondering if there is a way to accomplish this without needing to over-do everything.

AngularJS - How to load ng-view based on the URL?

I have been following the AngularJS tutorials on CodeSchool.
So I have views/index.html which contains all of my boilerplate code that is identical for each page. Then my templates for each page are in views/templates/ which I want included in the index.html page. So when the home page loads, it loads the views/index.html and includes the views/templates/index.html.
views/
index.html
templates/
index.html
contact.html
about.html
Currently I have
<div id="menu">
<a id="menu_home" href="/#/index" ng-click="menu.set(0)" ng-class="{current:menu.isSet(0)}">Home</a>
<a id="menu_hire" href="/#/hire" ng-click="menu.set(1)" ng-class="{current:menu.isSet(1)}">For Hire</a>
<a id="menu_info" href="/#/info" ng-click="menu.set(2)" ng-class="{current:menu.isSet(2)}">Info</a>
</div>
<div id="main">
<ng-view></ng-view>
</div>
which works great. So only the required html is requested and inserted into the page.
But my problem is that the URL doesn't change in the browser. So if a user went directly to mysite.com/contact it wouldn't work. How can I load the page correctly if the mysite.com/contact or mysite.com/about pages are accessed directly?
I have also got it working using the ngRoute module, but the same issue remains when a user goes directly to a page.
Thanks.
You should use ngRoute and $routeProvider similar to the following.
var navigationRoutes = angular.module('navigationRoutes', ['ngRoute']);
/**
* Load routes for navigation using ngRoute
*/
navigationRoutes.config(function ($routeProvider) {
$routeProvider
.when('/index', {
templateUrl: 'app/components/index/index.view.html',
controller: 'IndexCtrl'
})
.when('/contact', {
templateUrl: 'app/components/contact/contact.view.html',
controller: 'ContactCtrl'
})
.otherwise({
redirectTo: '/dashboard'
});
});
This way you can also specify a different controller based on the URL.
UPDATE
In your index page if you add -
<div class="view">
<div ng-view></div>
</div>
To your main index.html page the the contents of the $routeProvider selected file will be shown within this div. You just need to make sure that you add the tag for the controller.js files in the index.html page.
You will need to make these settings in the web server to redirect all urls to your index page where you load your angular app which in turn will handles the routes

ui-router duplicating ui-view during a transition

<html>
<head>
[...]
</head>
<body>
<div ui-view="body">
<header></header>
<div ui-view="main">
Something you see while angular/templates load.
</div>
<footer></footer>
</div>
</body>
</html>
stuff.js
var app = angular.module("app", ['ui.router']);
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('home', {
url: '/',
views: {
"main": {
controller: 'HomeController',
templateUrl: 'home.tpl.html'
}
}
});
$stateProvider.state('signin', {
url: '/signin',
views: {
"body": {
controller: 'SigninController',
templateUrl: 'signin.tpl.html'
}
}
});
}]);
I disabled javascript while making the state transition and this is what I see in the browsers inspector...
<html>
[...]
<body>
<div ui-view="body">
<header>[...]</header>
<div ui-view="main">[... home.tpl.html ...]</div>
</div>
<div ui-view="body">
[... signup.tpl.html ...]
</div>
</body>
</html>
I was shocked to see that ui-router actually duplicates the ui-view and creates one view before removing the old view.
Obviously this causes the problem that a combination of BOTH views are showing for at least two seconds while navigating from signin to home. This behavior is the same on all tested browsers. Is there a way to tell/force/trick ui-router into completely removing the template of one view before loading another view?
this is similar to: Preventing duplicate ui-view in AngularJS and the answer may apply to my situation as well.
EDIT
the first div had class="ng-enter ng-enter-active" and the next one had class="ng-leave ng-leave-active" answer follows from that.
I have noticed this as well. This answer: Angularjs - ng-cloak/ng-show elements blink states that ng-cloak is the ticket, but I haven't been able to get it to work in this scenario.
I'm not sure how you are moving between your routes, but you could set a property on the model used by the first view to true and use ng-show on the entire view with that variable. Then when you're ready to move to the second view, set that variable to false. I'm trying to resolve this myself and will report back if I find a more elegant solution.

ionic - ion-nav-view not working

I am building a ionic pacakage, having multiple views. I use the route provider to navigate between different views.
app.js
.config(function($routeProvider,$locationProvider){
$routeProvider
.when('/search',
{
controller : 'MyController',
templateUrl : 'partials/search.html'
})
.when('/not-found/:className',
{
controller : 'MyController',
templateUrl : 'partials/not-found.html'
})
My index.html
<body ng-app="MyApp">
<ng-view></ng-view>
</body>
</html>
The problem is that the back button on my phone does not work.i.e it does not remember the history.
e.g If I go from search.html to not-found.html, when I press the back button on my phone, I expect it to come back to search.html instead it closes my app.
I looked and ionic forum and the suggest way to make back button work is to use ion-nav-view. If I replace ng-view with ion-nav-view, the search/not-found page are not rendering, I even tried adding the ion-view on the search/not-found html page.
1) Could you please suggest a way to get my back button working?
In order to achieve that, you actually need to capture the hardware back button pressed event and perform the navigation accordingly or You can use ion-nav-back-button..
Capture the hardware back button event :
$ionicPlatform.registerBackButtonAction(function () {
if (condition) {
navigator.app.exitApp();
} else {
// handle back action!
}
}, 100);
More Details can be found here
Using ion-nav-back-button
<ion-nav-bar>
<ion-nav-back-button class="button-clear">
<i class="ion-arrow-left-c"></i> Back
</ion-nav-back-button>
</ion-nav-bar>
More Details about this can be found here
registerBackButtonAction is already handled as part of ion-nav-back-button as part of the ng-click attribute within the ion-nav-back-button definition: buttonEle.setAttribute('ng-click', '$ionicGoBack()') , since $ionicGoBack executes $ionicHistory.goBack() which in turn handles the hardware back button. A simple change to use state configuration should work fine as below:
angular
.module('app', ['ionic'])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('search', {
url: '/search',
controller : 'MyController',
templateUrl : 'partials/search.html'
})
.state('not-found', {
url: `/not-found/:className',
controller : 'MyController',
templateUrl : 'partials/not-found.html'
});
$urlRouterProvider.otherwise('/search');
});
HTML:
<body ng-app="app">
<ion-nav-bar>
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</body>
</html>

Angular JS - UI Routing - the script always scrolls down to the injection but I want them to see the whole page?

I am using a bootstrap template and I tried to implement Angular JS with ui.routing
The injection and navigation itself works fine... only my header includes a slider and the text is injected below. So every time someone access the route domain, he will by default get the home route; but after loading the site it automatically scrolls down to the injection part and the user does not see the header and the slider. How can I change that?
Here is part of my html code:
<header ng-include="'templates/header.html'"></header>
<div class="container">
<div class="row" >
<div ui-view></div>
</div>
<footer ng-include="'templates/footer.html'"></footer>
and here is my app.js
angular
.module('myApp', ['ui.router'])
.config(['$urlRouterProvider','$stateProvider',function($urlRouterProvider,$stateProvider){
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home',{
url: '/',
templateUrl: 'templates/home.html'
})
.state('about',{
url: '/about',
templateUrl: 'templates/about.html'
})
.state('contact',{
url: '/contact',
template: 'CONTACT'
})
}])
You should use autoscroll="false" setting:
http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.directive:ui-view
Example:
<div ui-view autoscroll="false"></div>
A cite:
autoscroll(optional) – {string=} –
It allows you to set the scroll behavior of the browser window when a view is populated.
And also few examples from doc:
<!-- If autoscroll present with no expression,
then scroll ui-view into view -->
<ui-view autoscroll/>
<!-- If autoscroll present with valid expression,
then scroll ui-view into view if expression evaluates to true -->
<ui-view autoscroll='true'/>
<ui-view autoscroll='false'/>
<ui-view autoscroll='scopeVariable'/>

Resources