Showing posts with label angularjs. Show all posts
Showing posts with label angularjs. Show all posts

Apr 8, 2016

AngularJs 2 Component: manually bind event listener to element

Sample code of binding element to an onchange event.

import {Directive, ElementRef, Output, EventEmitter, Renderer} from 'angular2/core';

@Directive({
  selector: 'my-comp'
})
export class myComp {
  constructor(el: ElementRef, renderer: Renderer) {
    renderer.listen(el.nativeElement, 'change', event => console.log(event));
  }
}

Stuff you need:
  • directive decorator
  • ElementRef.nativeElement
  • Renderer.listen()

Directive decorator
For my case here, I use directive decorator, because I do not need any template update.
If you are familiar with AngularJs 1.x, this is same as the directive with empty template like short example below:
eg.

angular.directive('myApp', function() {
  return {
    restrict: 'A',
    template: '',
    link: function() { ... }
  };
);


And of course you can choose to import Page, and use it with template like:

import {Page, ElementRef, Output, EventEmitter, Renderer} from 'angular2/core';

@Page({
  selector: 'my-app',
  template: 'Your template goes here'
})

// more code...


ElementRef.nativeElement
The similarity of ElementRef.nativeElement in AngularJs 2 with element parameter in Link() in AngularJs 1.x directive.


angular.directive('myApp', function() {
  return {
    restrict: 'A',
    template: '',
    link: function(scope, element, attributes) {
      // `ElementRef.nativeElement` is almost similar with
      // the `element` parameter in this link() function
    }
  };
);

Renderer.listen() - Angular2 beta 13
Add custom listener to keep track of an event fired, this helps at emitting or initiating additional action.
It works just like how AngularJs 1.x bind an event and initiate its parent's controller function in the scope.
Example AngularJs 1.x below:

angular
.controller('myCtrl', function() {
  scope.onClick = function(event) {
    console.log(event);
  };
})
.directive('myApp', function() {
  return {
    restrict: 'A',
    link: function(scope, element, attributes) {
      // it bind event to element as in Angular 1.x
      $(element).bind('click', function(event) {
        scope.onClick(event);
      });
    }
  };
);


In AngularJs 2, more complete version of the sample code from top which indicate the use of Renderer.listen()

import {
  Directive, 
  ElementRef, 
  Output, 
  EventEmitter, 
  Renderer, 
  Component,
  bootstrap
} from 'angular2/core';

@Directive({
  selector: '[my-comp]'
})
class myComp {
  @Output() click = new EventEmitter();
  constructor(el: ElementRef, renderer: Renderer) { 
    renderer.listen(el.nativeElement, 'click', (event) => {
      this.onClick(event);
    });
  }

  onClick(event){
    this.click.emit({
      value: event
    });
  }
}

@Component({
  template: '<button (click)="showclick($event)" my-comp></button>',
  directives: [myComp]
})
class myApp {
  showClick($event) {
   console.log('changes::', $event);
  }
}
bootstrap(myApp);



Reference/learning source: Dynamically add event listener in Angular 2

Jan 22, 2016

Implant / inject event function to every (change of src) page in iframe with AngularJs

To inject an event manually with AngularJs (from the outside of child iframe),
you'll need two key things:

  • window.onload()
  • window.onmousedown

You'll need an angular directive to help injecting the event function and iframe page being "load".

// inject touch event to iframe child body
angular.directive('iframe', function() {
  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
      element[0].onload = function() {
        scope.loaded();
      };
    },
    controller: function($scope, $window) {
      $scope.loaded = function() {
        $window.frames[0].window.onmousedown = function() {
          alert('Touched!');
        };
      };
    }
  };
});


Firstly, from element[0], you'll get your iframe element.
2nd, prepare a "loaded()" function to let "link()" to initiate for "onload()".


This solution made by the inspiration from AngularJS: onLoad from an iframe directive by Ashish Datta

Aug 25, 2015

Cordova, store image from data URL or base64

In order to get image resized and store the image right away, we need some workaround to achieve this result.

First, resize the image into thumbnail-like size
2nd, store the image into targeted directory

This is achievable with Phonegap-image-resizer


$window.imageResizer.resizeImage(function(resizedImage) {

  // Store image into local
  $window.imageResizer.storeImage(function(response) { // cache
    var filePath = response.filename,
        pathOnly = filePath.substring(0, sourceFile.lastIndexOf('/')) + '/',
        filename = filePath.split('/').pop().replace(/\#(.*?)$/, '').replace(/\?(.*?)$/, '');


    // store file into targeted location here with 
    // cordova official File plugin
    $cordovaFile.moveFile(pathOnly, filename, cordova.file.dataDirectory).then(function(success) {
      console.log(success);
    }, function(error) {
      console.log(errir);
    });


  }, function(error) {
    return error;

  }, resizedImage.imageData, {
    imageDataType: ImageResizer.IMAGE_DATA_TYPE_BASE64,
    format: 'jpg',
    filename: // new name,
    directory: // location to store,
    quality: 80
  });

}, function(error) {
  return error;

}, photo.url, 0.2, 0.2, {
  imageDataType: ImageResizer.IMAGE_DATA_TYPE_URL,
  resizeType: ImageResizer.RESIZE_TYPE_FACTOR,
  format: 'jpg'
});


Two parts here:


TL;DR

1st step, $window.imageResizer.resizeImage will resize the image
2nd step, $window.imageResizer.storeImage store image

Cursory go through resizeImage.js to better understand how to utilise the code.

Reference: Converting Large Images to Base64Strings in Ionic Framework

Aug 4, 2015

OnsenUI: Change tab without pressing ons-tabber's ons-tab (with AngularJs)

I have been searching around for changing tab with AngularJs $scope function, without pressing on the ons-tabber's tab.
This function will do the trick setActiveTab()
First, you have to specify name for the tabbar,
(eg. ons-tabbar[var="myTabbar"])

use setActiveTab() with index (just like array, start from 0) for myTabbar:
myTabbar.setActiveTab(1) for my case below.

AngularJs

var app = angular.module('app', ['onsen']);

app.controller('myCtrl', ['$scope', function($scope) {
  $scope.goHome = function() {
    // setActiveTab(index, options)
    myTabbar.setActiveTab(1, {animation: 'fade'});
  };
}]);

Html

<ons-page ng-controller="myCtrl">
  <ons-toolbar>
    <div class="right">
      Toolbar - myCtrl
    </div>
  </ons-toolbar>
  
  <ons-button ng-click="goHome()">Go Home</ons-button>

  <ons-tabbar var="myTabbar">
    <ons-tab active="true" icon="ion-images" label="App" no-reload="" page="app.html" persistent=""></ons-tab>
    <ons-tab icon="fa-user" label="Home" no-reload="" page="home.html" persistent=""></ons-tab>
  </ons-tabbar>
</ons-page>

Summary
The main part:

  • use variable name for ons-tabbar
  • use setActiveTab(index) with the tabbar variable name to redirect

Jun 3, 2015

AngularJs UI-Router conditional Otherwise link

For easier handling of redirection of $state,
when our angularJs app handling an unknown $state name,
it'll refer to $urlRouterProvider.otherwise("/"); which have to be written inside "config()".
assuming your angular app is declared as below:

var app = angular.module([]);

app.config(['$urlRouterProvider', function($urlRouterProvider) {
  $urlRouterProvider.otherwise(function($injector, $location) {
    var AuthService= $injector.get("AuthService");
    if (AuthService.isLoggedIn()) {
      return "main";
    } else {
      return "login";
    }
  });
}]);
this allow your otherwise become dynamic depend on the login status of a user. In the code above, AuthService is an example authentication service to help determine if a user is logged in.