Enable tapping: angular 1.2, ngMobile and ng-click? - mobile

Using angular 1.2, I included the angular-mobile.js file and add the ngMobile module to my module dependencies list.
Directives 'ng-swipe-left' and 'ng-swipe-right' work well but the 'ng-click' doesn't seem faster. It seems that there's still this 300ms delay on ipad...
Is something more required to use this feature?
By the way, what's the difference between the module ngTouch and ngMobile? Swipe directive seems to works including one either.
Thanks!

I have the same issue, and I'm not using jQuery. I have resorted to fastclick, and the app feels much more responsive. Yes, ngTouch is the new version of ngMobile, but in its current state it can only be used for swiping, it seems.

It seems that the issue is known and happen when jQuery is loaded:
https://github.com/angular/angular.js/issues/2548
(according 'AngularJS 1.2 And Beyond' talk, ngTouch will be the new name of NgMobile)

Look at this answer, the solution works also for angular ng-click directive.
Basically you just need to do this in stop method of jquery-ui-draggable:
$('.selector').draggable({
stop: function(event, ui) {
// event.toElement is the element that was responsible
// for triggering this event. The handle, in case of a draggable.
$( event.toElement ).one('click', function(e){ e.stopImmediatePropagation(); } );
}
});

I'm using the latest angular and ngtouch 1.2.10 and am also using jQuery. I'm still seeing the same issue you are. I added faskclick and it fixed it. Looks like there is at least one issue open on github for this problem so presumably this will be fixed at some point.
// This code should be added outside of and angularjs code.
window.addEventListener('load', function () {
FastClick.attach(document.body);
}, false);

Related

Android back button not working with hybrid app ~ using onsen ui (angular js) building app using crosswalk

When I build the hybrid app using crosswalk - android Back button is not working with onsen ui framework(using angular js).
Below is the code which i have used...
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
// Handle the back button
alert("Backbutton is pressed!");
var element = document.querySelector(".navigator-container");
var scope = angular.element(element).scope();
scope.popPage();
}
As #kabaehr mentioned you may need to wait for everything to be ready first. That means either of the following:
document.addEventListener('deviceready', function(){ ... });
ons.ready(function(){ ... });
The other thing which may be specific to Onsen UI is the fact that it's already doing some handling of that event, so you could try to use the API which is given for that.
Here are the docs for that API. Currently it seems like the method which you want is:
ons.setDefaultDeviceBackButtonListener(onBackKeyDown)
Although that method doesn't sound too nice so maybe the name will change in the future.
For now feel free to try if any of these options seem to work for you.

ChartistJS : Converting jQuery solution to AngularJS

I am using Chartist JS for my charts in my Angular JS app. The issue is I am seeing this here. There is a JS bin that highlights the issue. The author gives a solution for it. The solution is doing DOM manipulations in Jquery which is easy to do. However with AngularJS the way you manipulate the DOM is via Directives. I have created a plunker here which highlights the same issue in Angular JS but I am confused as to how to put the solution provided by author into my Angular code.
Here is the solution
$('[data-tab]').on('toggled', function (event, tab) {
tab.find('.ct-chart').each(function(i, e) {
e.__chartist__.update();
});
});
Edit: As requested the JSFiddle is updated, so what I am trying to do is. I have three different tabs and three different graphs, whenever I click on them I should see the respective graph. To make the tab behavior possible I have written a basic code using scope and model. which facilitates the changing of tabs. The issue is that the chart is getting created for first or default tab but not for the second and third tab. There is a solution given by the author but I don't know how to implement that in AngualrJS
the jQuery solution that you post is basically finding all the chart references and then doing DOM manipulation and call the update() function.
The key is how to find the chart to update in Angular.
In this case, you can assign a variable when you create a chart. For example:
var chart4 = new Chartist.Bar('#chart4', data1);
var chart5 = new Chartist.Bar('#chart5', data2);
Now you have the reference of the chart. All you have to do is to call update() function to render the chart again.
if (value === "allDrivers") {
$scope.tab = "All";
chart4.update();
}
Here is the working plunker
One thing I like to point out is: right now you need to double click the tab in order to see the chart is being rendered or you resize the browser window. I am still trying to find a way to fix this. But at least this approach gives you an idea how to convert the jQuery solution to Angular solution.
I was able to solve this using angular.element() method. So if you wish you use jquery in your angular code. You have to do this via angular.element method. But make sure to include jquery before angular in your index.html
If jQuery is available, angular.element is an alias for the jQuery
function. If jQuery is not available, angular.element delegates to
Angular's built-in subset of jQuery, called "jQuery lite" or jqLite.
I did not know this. From here it was learning for me. Following advice of #pieterjandesmedt from this post. I was able to do this. For other people who want to learn how this works. I have created a GitHub repo which gives a solution to this issue. The link for problem is given in the question. Hope that helps

Why does finally and done of $animateCSS behave differently in UI Bootstrap Angular JS

I am using UI Bootstrap for collapsing/expanding a div section based on user clicking a button similar to the example shown in the official site - UI Bootstrap-Collapse
I included the latest version of ui-bootstrap(0.14.2) but it was not showing the expected behavior. In particular the collapseDone() and expandDone() callbacks are never called after the $animateCSS is done the animations. (The animations are working properly, presumably because of the css transition property of the class 'collapsing' in twitter bootstrap.)
But when I inspected the UI Bootstrap site, I found that it's working properly as expected. (That's the class 'collapsing' is added during the animation and then removed after animation and then the class 'collapse' is added). So I checked the source code link for collapse collapse source code -github and found that finally is used for $animateCSS promise resolution rather than done in the ui.bootstrap.js code I included.
So could someone please explain the difference between finally and done methods of the $animateCSS function? The documentation [Angular Docs-$animateCSS][3] says that
there is also an additional method available on the runner called .done(callbackFn). The done method works the same as .finally(callbackFn), however, it does not trigger a digest to occur. Therefore, for performance reasons, it's always best to use runner.done(callback) instead of runner.then(), runner.catch() or runner.finally() unless you really need a digest to kick off afterwards.
So it looks like both should behave similarly. Could someone shed light on this, as there seems to be very little resources to learn about $animateCSS. (google search for $animateCss returns results for animate.css which seems to be part of the earler angular js verion (v1.2) - so that doesn't help)
I had forgotten to inject "ngAnimate" to my module. That way the animation by $animateCss was not successful, so the done() was never called. But finally will be called even if the animation is not successful.

The event $scope.$on('$destroy') doesn't work updating ionic & angular

I use $interval and need to detect when the controller is destroyed. Until now, I have used the $destroy event and it worked perfectly. For example with this basic code, it prints "destroy" in the console when I go to another page (with a simple <a href="#/myNewUrl"> in myView.html).
angular.module('myModule').controller('myController', ['$scope', function($scope) {
$scope.$on('$destroy', function() {
console.log('destroy');
});
}]);
But since I updated Ionic to the new version (v1.0.0-beta.14), that uses the new version to Angular too (v1.3.6), the $destroy event isn't detect when I go to another page.
Does anybody get the same problem? How can I be resolve it?
Thank you for your answer!
EDIT:
I have finally fixed the problem!!! Now, with the new Ionic version, the view is cached automatically. Adding cache-view="false" in the template disable it.
But I found a best way than the destroy event. Ionic added new events (on $ionicView) and now you can detect when you leave the page (and the page stays cached) with: $ionicView.leave.
To get more information: http://ionicframework.com/docs/nightly/api/directive/ionView/
Is your template cached? If you don't have cache: false in your state routes, then the controller is not destroyed.
http://forum.ionicframework.com/t/how-to-destroy-controllers-in-ion-tab-directive/16658
It's a hello from Ionic dev team. They like to leak memory, you see.
Just set
$ionicConfigProvider.views.maxCache(0);
That should do it

ng-repeat moves dom elements around, which breaks a ckeditor because it doesn't support having it's dom elements moved

I'm trying have an ng-repeat which contains divs that include a CKEDITOR instance. The list is sortable by a few different properties. However, when the list is resorted, the CKEDITORs break because they don't support being moved around in the DOM. The only solution I can think of is to destroy the CKEDITOR instance before sort, and recreate them after. Is there any events on ng-repeat that can accomplish this?
plunkr here: http://plnkr.co/edit/tGnTdzvRl7xhEX7zYq4c?p=preview
Was able to get this fixed eventually. Pretty easy now that I think about, but took me 3 days to realize it. Instead of trying to listen for events on ng-repeat, catch the event that is causing the data to be modified. For me, it was jquery UI sortable (angular directive.) In the controller add $scope.$broadcast('unbind-ckeditor') before the change, and then $scope.$broadcast('rebind-ckeditor') after it. In your angularjs directive for ckeditor, call scope.$on('unbind-ckeditor', function() {instance.destroy /* instance is your ckeditor instance*/}); and then reload it in the rebind. Hope this helps someone.
Edit:
Make sure the $on('unbind-ckeditor'... is only added to the scope once, or multiple sorts will throw exceptions.
The solution for me:
use divArea and not iframe, this will work with ng-repeat when the list changed.
using other textarea (hidden) and monitoring it as the ng-sortable+ckeditor broke the order of CKEditors.
in ng-sortable (who make the change in the list) I was added this code:
$rootScope.$broadcast('rebind-ckeditor'); console.log("rebind")
and in CKEDITOR directive:
scope.$on('rebind-ckeditor', function () {
if (jQuery(element).data("loaded")) {
console.log("rebind");
CKEDITOR.instances[element[0].id].destroy();
jQuery(element).data("loaded", null);
element[0].value = $("textarea", element.parent())[1].value; // update manualy from the hidden textarea
onLoad(); //recreate CKE after textarea changed.
}
})

Resources