Ionic/Angular custom page transition - angularjs

I'm working on an Ionic app that has a "preloader" immediately before the app starts. Ideally I'd like the main page after the pre-loader to appear immediately, instead of slide-in. Is there a way to programmatically define what transition to use on a one-off basis? Normally the sliding is fine, but just not for the transition from the pre-loader to the main menu.

Defining in controller $ionicViewSwitcher and $state
now in ng-click inside a or button tags call:
//here transition name
$ionicViewSwitcher.nextDirection('forward');
//here next state name
$state.go("main.map");

angular.module('YOUR_APP_NAME_HERE').config(function($ionicConfigProvider){
$ionicConfigProvider.views.transition('none');
});
Hope this helps you.

Related

angular-ui-swiper: swiper is not defined

I am using the angular-ui-swiper and I want to set the active slide depending on the URL-Parameter. I have an angular controller, where the data is loaded for the swiper. This works fine, the buttons are working (prev, next). I call the method slideTo to set the activeslider after link click in the navigation. But it is not working if I load the page with the special parameter. The swiper-instance is not defined. So I have to call the correct page lifecycle event. I used the load, init-events, an equivalent to document ready, but without any success. It is only working if I put my setActiveSlide-Method to the scroll-event :D
Do you have any idea?
Thanks in advance
Maybe you need to make the set the activeslider in this kind of block:
angular.element(document).ready(function () {
//code here
});
Can you make a jsfiddle so we can see your code?

How to push the initial page resetting the pages stack?

i'm using Onsen (v1.3.12) and Angular to develop my cross-platform app.
I added a button to go back to the home page of the app, so if users make some pop or some push of pages, when they hit on "Home" button they go back to initial page.
I use the following code:
$rootScope.myNavigator.resetToPage('homepage.html');
but it doesn't show the animation effect of "popping page" that is visible with pushPage method.
To get this effect i have to use the following code:
$rootScope.myNavigator.pages.length = 1;
$rootScope.myNavigator.pushPage('splash.html');
$timeout(function() {
$rootScope.myNavigator.pages.length = 0;
});
Isn't the default behaviour of resetPage method weird? Why it doesn't show the "pop" effect?
I solved using animation option:
$rootScope.myNavigator.resetToPage('splash.html', {animation: 'slide'});
The weird thing is that pushPage, popPage and resetPage methods have default animation option set to slide. The same doesn't happen for resetPage method.
Maybe is a Onsen bug.

Handling page or tab change in angualajs

How to detect unsaved page changes check while moving another page or tab in angularjs 1.5 application.
One of approach is using directives however how to pass related form named to the directive instead of using hard coded solution?
I tried using the service approach as mentioned below but my nested view controller is not able to access the form name. Iam getting $scope.myForm as undefined.
You can handle page change with the event $locationChangeStart for ng-route or $stateChangeStart for ui-router (perform the logic you want inside):
$scope.$on('$locationChangeStart', function(event) {
if ($scope.myForm.$invalid) {
event.preventDefault();
}
});
To tab change etc, you can disable your tab with something like or watever approach you prefer
ng-disabled="!myForm.$valid"
EDIT
You may look at this post to use a service/factory approach :
https://stackoverflow.com/a/25459689/5138917
The module below seem to work for me
https://github.com/facultymatt/angular-unsavedChanges

Call function when a tab in tabbar is first opened (onsen-ui)

I need to load a specific JavaScript function after one of the tabs in the tabbar finishes loading (after it is clicked for the first time). I don't really understand how to set up an event listener with the onsen-ui tabbar (ons-tabbar), and the docs were not very clear.
Basically, what I am trying to do, is create a few graphs on one of the pages. This page is loaded up when a ons-tab is selected and the partial loads. However, I need the JavaScript that creates the graphs to only load after the page is loaded (the JavaScript looks for the elements to position the graph in the partial, hence my problem right now is that the JS is loading first and not finding the html elements in the partial because they have't been loaded yet). How do I create an event listener to detect when one of the tabs are selected to run a specific code of JavaScript?
To be a little bit more clear, I am using the persistent attribute on this specific tab, so essentially I only need this event listener to run the JS code once, when the tab is first opened. However, I don't understand how to get the once event listener to work...
For the reference: http://onsen.io/reference/ons-tabbar.html#methods-summary
There are three tabbar methods related to events: on, once and off.
That means the way to use them is myTabbar.on(...), for example. You can see in that link their parameters as well. Also, right below there are the three tabbar events. In this case I think you want to use postchange, right?
In your HTML you create a tabbar and assign it to a variable with var attribute, as I am sure you already know:
<ons-tabbar var="myTabbar">
<ons-tab page="tab0.html" label="Tab0" active="true"></ons-tab>
<ons-tab page="tab1.html" label="Tab1"></ons-tab>
<ons-tab page="tab2.html" label="Tab2"></ons-tab>
</ons-tabbar>
Now, you have to wait until the app is initialised and Onsen UI is loaded in order to set the event listeners, and you can use ons.ready() for that.
Going back to the tabbar events method, since you only need to trigger the functionality with a specific tab you need to filter the tabs inside the listener. Therefore, if you use myTabbar.once('postchange', ...) the listener itself will be triggered only once regardless the filter you set inside, so perhaps it will be triggered with a different tab and then deleted for the tab you want. You cannot use it in this case.
Instead of that, you can set a listener with myTabbar.on('postchange', ...) that triggers always, then filter the tabs inside and remove the listener only when you want with myTabbar.off('postchange'). Something like this:
ons.ready(function() {
myTabbar.on('postchange', function(event) {
// Only with the tab we want, we can use the index or the name
if (event.index === 2) {
console.log('postchange and do stuff with the tab');
console.log(event.tabItem);
// Delete this listener so it's only triggered the first time
myTabbar.off('postchange');
}
});
Working here: http://codepen.io/frankdiox/pen/QbYEaq
In case you have other listener over postchange, you can use the second parameter of myTabbar.off(...) to remove the exact listener you want and not the others.
Hope it helps!

Updating URL in Angular JS without re-rendering view

I'm building a dashboard system in AngularJS and I'm running into an issue with setting the url via $location.path
In our dashboard, we have a bunch of widgets. Each shows a larger maximized view when you click on it. We are trying to setup deep linking to allow users to link to a dashboard with a widget maximized.
Currently, we have 2 routes that look like /dashboard/:dashboardId and /dashboard/:dashboardId/:maximizedWidgetId
When a user maximizes a widget, we update the url using $location.path, but this is causing the view to re-render. Since we have all of the data, we don't want to reload the whole view, we just want to update the URL. Is there a way to set the url without causing the view to re-render?
HTML5Mode is set to true.
In fact, a view will be rendered everytime you change a url. Thats how $routeProvider works in Angular but you can pass maximizeWidgetId as a querystring which does not re-render a view.
App.config(function($routeProvider) {
$routeProvider.when('/dashboard/:dashboardId', {reloadOnSearch: false});
});
When you click a widget to maximize:
Maximum This Widget
or
$location.search('maximizeWidgetId', 1);
The URL in addressbar would change to http://app.com/dashboard/1?maximizeWidgetId=1
You can even watch when search changes in the URL (from one widget to another)
$scope.$on('$routeUpdate', function(scope, next, current) {
// Minimize the current widget and maximize the new one
});
You can set the reloadOnSearch property of $routeProvider to false.
Possible duplicate question : Can you change a path without reloading the controller in AngularJS?
Regards
For those who need change full path() without controllers reload
Here is plugin: https://github.com/anglibs/angular-location-update
Usage:
$location.update_path('/notes/1');
I realize this is an old question, but since it took me a good day and a half to find the answer, so here goes.
You do not need to convert your path into query strings if you use angular-ui-router.
Currently, due to what may be considered as a bug, setting reloadOnSearch: false on a state will result in being able to change the route without reloading the view. The GitHub user lmessinger was even kind enough to provide a demo of it. You can find the link from his comment linked above.
Basically all you need to do is:
Use ui-router instead of ngRoute
In your states, declare the ones you wish with reloadOnSearch: false
In my app, I have an category listing view, from which you can get to another category using a state like this:
$stateProvider.state('articles.list', {
url: '{categorySlug}',
templateUrl: 'partials/article-list.html',
controller: 'ArticleListCtrl',
reloadOnSearch: false
});
That's it. Hope this helps!
We're using Angular UI Router instead of built-in routes for a similar scenario. It doesn't seem to re-instantiate the controller and re-render the entire view.
How I've implemented it:
(my solution mostly for cases when you need to change whole route, not sub-parts)
I have page with menu (menuPage) and data should not be cleaned on navigation (there is a lot of inputs on each page and user will be very very unhappy if data will disappear accidentally).
turn off $routeProvider
in mainPage controller add two divs with custom directive attribute - each directive contains only 'templateUrl' and 'scope: true'
<div ng-show="tab=='tab_name'" data-tab_name-page></div>
mainPage controller contains lines to simulate routing:
if (!$scope.tab && $location.path()) {
$scope.tab = $location.path().substr(1);
}
$scope.setTab = function(tab) {
$scope.tab = tab;
$location.path('/'+tab);
};
That's all. Little bit ugly to have separate directive for each page, but usage of dynamic templateUrl (as function) in directive provokes re-rendering of page (and loosing data of inputs).
If I understood your question right, you want to,
Maximize the widget when the user is on /dashboard/:dashboardId and he maximizes the widget.
You want the user to have the ability to come back to /dashboard/:dashboardId/:maximizedWidgetId and still see the widget maximized.
You can configure only the first route in the routerConfig and use RouteParams to identify if the maximized widget is passed in the params in the controller of this configured route and maximize the one passed as the param. If the user is maximizing it the first time, share the url to this maximized view with the maximizedWidgetId on the UI.
As long as you use $location(which is just a wrapper over native location object) to update the path it will refresh the view.
I have an idea to use
window.history.replaceState('Object', 'Title', '/new-url');
If you do this and a digest cycle happens it will completely mangle things up. However if you set it back to the correct url that angular expects it's ok. So in theory you could store the correct url that angular expects and reset it just before you know a digest fires.
I've not tested this though.
Below code will let you change url without redirection such as: http://localhost/#/691?foo?bar?blabla
for(var i=0;i<=1000;i++) $routeProvider.when('/'+i, {templateUrl: "tabPages/"+i+".html",reloadOnSearch: false});
But when you change to http://localhost/#/692, you will be redirected.

Resources