Loading ng-view html templates - angularjs

I have one index.html page and I am using ng-view. The two HTML templates are page1 and page2.
I have a button to which I have attached an ng-click function. When the function is fired, I am fetching weather data using $resource and also using the weather url inside amcharts dataloader to make a graph from weather information.
Now, if I do not separate the templates and keep everything on one page, everything works fine. But when I separate them and take the input from the index.html page, nothing works. I guess because when page1 and page2 are loaded, the information fetched by the function is lost.
Is there an elegant way to do this? Ideally I want my index.html to take input from the user. Like, "enter city" and I want that when I load /page1 there should be the weather data and on page2, the weather chart, without again asking for input from the user.
Right now I am taking the input in page1 but ideally I would like it to be in main index.html.
I am sure that the code is correct and I am correctly using routing and this is more of an error that has to do with the logic and priority of execution.
I am still quite new to angularjs. So please :)
JavaScript
$app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'page1.html',
controller: 'weatherController'
})
.when('/graph', {
templateUrl: 'page2.html',
controller: 'weatherController'
})
.otherwise({
redirectTo: '/'
})
});
app.controller('weatherController', ['$scope', '$resource', '$routeParams', function($scope, $resource, $routeParams) {
$scope.GetWeatherInfo = function() {
// getting weather data for page1.html
// getting chart data for page2.html
...
}
}]);
HTML (Page1.html)
<div ng-controller="weatherController">
<input type="text" name="city" id="city" class="form-control" placeholder="Stadt" ng-model="city_name" />
<button id="submitWeather" class="btn btn-primary" ng-click="GetWeatherInfo()"> zum Wetter </button>
Temperature: Min: {{w.main.temp_min}}
Max: {{w.main.temp_max}}
HTML (Page2.html)
<div ng-controller="weatherController">
<div id="chartdiv"></div>

Related

Angular refresh current page - problems

home.html is a template with two fieldsets.
I use ng-show to make the first fieldset visisble when the page loads and when a user clicks a button the other fieldset is made visible and the first one hidden.
This is accomplished by using a variable 'preview' like so (this is a jsfiddle) :
<div ng-app="app">
<div ng-controller="MainController">
<fieldset ng-show="!preview">
<p>This is fieldset 1</p>
<button ng-click="toggleIt()">Toggle</button>
</fieldset>
<fieldset ng-show="preview">
<p>This is fieldset 2</p>
</fieldset>
Home
</div>
</div>
and the controller is like:
angular.module('app', []).
controller('MainController', ['$scope', function ($scope) {
$scope.preview = false;
$scope.toggleIt = function(){
$scope.preview = true;
}
$scope.returnIt = function(){
location.reload();
}
}]);
In JsFiddle it works fine but when I use the 'Home' link in my angular app which is:
Home
and this is picked up by the app.routes.js file
.when('/', {
templateUrl : 'app/views/pages/home.html',
controller: 'MainController',
controllerAs: 'main'
})
Nothing happens - fieldset 2 is still visible rather than fieldset 1.
I was expecting that $scope.preview would be set to false as this is the first line in the controller and that would make the first fieldset visible again.
When I do a browser refresh it works but not using the routing.
I have tried location.reload(); (and this works in the fiddle), but when I apply it inside the app controller I get TypeError: $location.reload is not a function.
I have tried $route.reload() which sends it into an infinite loop, and window.location.reload() which keeps reloading.
Is there a simple way I can achieve a browser-like refresh of the page via the routing?

How to prevent losing data when moving from one state to another in multi-step form?

I am new to web programming and especially to AngularJS.
So maybe my question will seem naive to some of you.
I'm developing a single page application using angular-ui-router.
I have created a multi-step form that contains 3 states:
(function () {
"use strict";
angular.module("sensorManagement", ["ui.router", "ngAnimate", "ngResource", "toaster"])
.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterPorvider) {
$urlRouterPorvider.otherwise("/Sensor/Home");
$stateProvider
.state("MultiStepForm", {
url: "/Sensor/MuiltyStepForm",
templateUrl: "/app/MultiStepForm/MuiltyStepForm.html",
})
.state('MultiStepForm.step1', {
url: '/step1',
templateUrl: '/app/MultiStepForm/FormStep1.html'
})
.state('MultiStepForm.step2', {
url: '/step2',
templateUrl: '/app/MultiStepForm/FormStep2.html'
})
.state('MultiStepForm.step3', {
url: '/step3',
templateUrl: '/app/MultiStepForm/FormStep3.html'
});
}]);
})();
Here is the HTML code:
<!-- form.html -->
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-multiple-step">
<div class="page-header text-center">
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref=".step1"><span>STEP1</span></a>
<a ui-sref-active="active" ui-sref=".step2"><span>STEP2</span></a>
<a ui-sref-active="active" ui-sref=".step3"><span>STEP3</span></a>
</div>
</div>
<form id="single-form">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
</div>
</div>
As you can see I have 3 states and each state has it's own view. The views have multiple elements (textboxes and checkboxes).
When the user enters some data for the STEP1 view and moves to the next step (STEP2 or STEP3) then at some point goes back to STEP1 all data is deleted. I checked with fiddler and can see that when I move from one state to another a call is made to the server and a new view generated.
My question is how can I prevent the lose of data when I move from one state to another? Do I have to use caching? Or maybe there is another way to prevent server calls and keep the data alive until the submit button clicked.
When you feel you have to save data across your controllers in your app. you should use a service.
app.factory('sharedDataService', function ($rootScope) {
console.log('sharedDataService service loaded.');
// do something here that can be shared in other controller
});
//pass this service in your controller to use it there
app.controller('Controller2', ['$scope', 'sharedDataService', function ($scope, sharedData) {
console.log('Controller2 controller loaded.');
//get data from shared service
}]);
find a useful Fiddle here
Cheers if it helps!
I think what you need to do is share you $scope between the parent and child stats. here is the stackoverflow post with good example. https://stackoverflow.com/a/27699798/284225

ui-route not redirecting to external page

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.

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>

Unable to display angularjs page data after route change.

I am relatively new to angularjs and seems like I am missing something obvious here. I tried to go through documentation and tutorials, but unable to find any solution to my problem.
I have a REST service at "localhost:8080/app/rest/schools/{schoolId}/selectedindicators". I can display the results in an angularjs app page (selectedindicator.html) like so:
<tbody>
<tr ng-repeat="selectedindicator in selectedindicators">
<td>{{selectedindicator.id}}</td>
<td>{{selectedindicator.school.name}}</td>
<td>{{selectedindicator.userId}}</td>
<td>{{selectedindicator.dateVisit}}</td>
<td>
<button type="submit"
ng-click="update(selectedindicator.id)"
class="btn">
<span class="glyphicon glyphicon-pencil"></span> Edit
</button>
</td>
</tr>
</tbody>
Until this point everything is working fine. But, when I try to select one of the selected indicators by clicking on the Edit button I can not display the data on the Edit (selectedindicatorForm.html) page. Here is chunk of my Edit page.
<div>
<div class="form-group">
<label>ID</label> <input type="text" class="form-control" name="id"
ng-model="selectedindicator.id" required>
</div>
.
.
.
.
.
.
</div>
Here is my routeProvider code:
myApp
.config(['$routeProvider', '$httpProvider', '$translateProvider',
function ($routeProvider, $httpProvider, $translateProvider) {
$routeProvider
.when('/selectedindicator', {
templateUrl: 'views/selectedindicators.html',
controller: 'SelectedIndicatorController',
resolve:{
resolvedSelectedIndicator: ['SelectedIndicator', function (SelectedIndicator) {
return SelectedIndicator.query();
}]
}
})
.when('/selectedindicatorForm',{
templateUrl: 'views/selectedindicatorForm.html',
controller: 'SelectedIndicatorFormController',
})
}]);
Here is my controller code for the update method:
myApp.controller('SelectedIndicatorController', ['$scope', '$location', '$route','resolvedSelectedIndicator', 'SelectedIndicator',
function ($scope, $location,$route, resolvedSelectedIndicator, SelectedIndicator) {
$scope.selectedindicators = resolvedSelectedIndicator;
$scope.update = function (id) {
$scope.selectedindicator = SelectedIndicator.get({id: id});
$location.path("/selectedindicatorForm");
};
}]);
you can add a separate service (singleton object) to pass data between controllers .
looks like you SelectedIndicator (which is passed onto SelectedIndicatorController) is already doing that and you can simply re-use it .
On your SelectedIndicatorFormController inject this service SelectedIndicator and call SelectedIndicator.get({id: id});
Note - looks like this line $scope.selectedindicator = SelectedIndicator.get({id: id}); inside SelectedIndicatorController doesn't serve any purpose.
If you could setup a plunk, I could help you.
Is there some reason you're transitioning using $location.path?
The way I'd do that would be just put an or something, with a class="btn" or some other css styling if you really want it to look like a button. With regular ngRoute, you just work with URLs, and should put all the state into the URL. I'm pretty sure setting a $scope variable and then manually changing the state doesn't actually do anything, since the new state has its own $scope.
To be perfectly frank after looking at that code, I'm going to say that you probably ought to read some angular tutorial stuff. I found egghead.io to be pretty great myself.

Resources