Showing posts with label angular Components. Show all posts
Showing posts with label angular Components. Show all posts
ngDraggable

ngDraggable

September 27, 2018
Drag and drop module for Angular JS with support for touch devices. demo.

Usage:

  • Install: bower install ngDraggable
  • Add angular and ngDraggable to your code:
 <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>  
 <script src="ngDraggable.js"></script>  
  • Add a dependency to the ngDraggable module in your application.
 angular.module('app', ['ngDraggable']);  
  • Add attribute directives to your html:
Draggable usage:
 <div ng-drag="true" ng-drag-data="{obj}" ng-drag-success="onDragComplete($data,$event)" ng-center-anchor="true">  
  Draggable div  
 </div>  
  • ng-center-anchor is optional. If not specified, it defaults to false.
  • If the draggable is also clickable (ng-click, ng-dblclick) the script wont react.
  • You can define a drag-button as child with the attribute ng-drag-handle.
ng-drag-start and ng-drag-move is also available. Add to the ng-drop element. ng-drag-stop can be used when you want to react to the user dragging an item and it wasn't dropped into the target container.
draggable:start, draggable:move and draggable:end events are broadcast on drag actions.
Drop area usage:
 <div ng-drop="true" ng-drop-success="onDropComplete($data,$event)" >  
  Drop area  
 </div>  

Angular Controller:

 app.controller('MainCtrl', function ($scope) {  
   $scope.onDragComplete=function(data,evt){  
     console.log("drag success, data:", data);  
   }  
   $scope.onDropComplete=function(data,evt){  
     console.log("drop success, data:", data);  
   }  
  };  

Examples

Drag and drop.
Re-ordering.
Cloning.
Canceling.

Pull requests

We welcome pull requests but please check that all the examples still work if you modified the source base. There have been serveral PRs recently that broke core functionality. If you are feeling really keen you could include some protractor test cases in your PR.
Note: Special thanks to Philip Andrews
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
ngx-bootstrap

ngx-bootstrap

September 22, 2018
Native Angular directives for Bootstrap http://valor-software.com/ngx-bootstrap

Links

Table of contents

  1. Getting Started
  2. Installation instructions
  3. Usage & Demo
  4. API
  5. Troubleshooting
  6. Contributing
  7. License

Getting Started

ngx-bootstrap contains all core (and not only) Bootstrap components powered by Angular. So you don't need to include original JS components, but we are using markup and css provided by Bootstrap.

Installation instructions

Install ngx-bootstrap from npm
 npm install ngx-bootstrap --save
You will need bootstrap styles (Bootstrap 3)
 

Or Bootstrap 4
 

To enable bootstrap 4 theme templates in ngx-bootstrap, please read this.

Usage & Demo

Main source of API documentation and usage scenarios available here: https://valor-software.com/ngx-bootstrap/
Additionally you can find demos and docs deployed from latest code with angular v4 and angular v5
Server side rendered version of this documentation available here

API

Check demo page for API reference

How to use it with:

How to build lib for development

First time
  • clone repository
  • npm install
  • npm run test it will build the lib and create a link in node_modules
To run bootstrap 3 and 4 demo:
  • npm run demo.serve to serve local demo. This is for testing only, without watchers.
For local development run
  • npm run build.watch in first terminal
  • ng serve in second
If you want to run the demo with Angular Universal:
  • npm run demo.serve-universal

Troubleshooting

So if you are in trouble, here's where you can look for help.
The best place to ask questions is on StackOverflow (under the ngx-bootstrap tag) You can also join our Slack channel and link your stackoverflow question there. But try to avoid asking generic help questions directly on Slack since they can easily get lost in the chat. You can also search among the existing GitHub issues.
If, and only if, none of the above helped, please open a new issue.

Note: Special thanks to Valor Software
Contact: dmitriy.shekhovtsov@valor-software.com
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
@ngui-react

@ngui-react

September 11, 2018
Angular2 Directive For React Component

Note:

After 0.3.0 or higher, ng2-react has been changed to @ngui/react. Here are the changes;
  • Module ng2-react is changed to @ngui/react
  • Direvtive ng2-react is changed to ngui-react
  • Class name Ng2React is changed to NguiReact

With @ngui/react, we can do the following from Angular2

  • Pass read-only props to React component
  • Call a function in React component
  • Fire event in React componet
  • Set state of React componet
You need more? Please log a feature requirement

How Does It Work

  1. Angular renders ngui-react component with the following attributes;
  • reactComponent, A React component to render. Let's call it as MyComp.
  • reactProps, react props for the React component, MyComp.
  • reactState, the initial state to be used by MyComp
  1. ngui-react create and render React component using;
  • React.createElement()
  • React.render()

Access ReactJS properties

You can access react element and instance from Angular component.
  • reactElement: the react element from React.createElement()
  • reactInstance: the react instance from React.render()

Install

  1. install @ngui/react
     $ npm install @ngui/react --save  
    
  2. import NguiReactModule to your AppModule
  3.  import { NgModule } from '@angular/core';  
      import { FormsModule } from "@angular/forms";  
      import { BrowserModule } from '@angular/platform-browser';  
      import { AppComponent } from './app.component';  
      import { NguiReactModule } from '@ngui/react';  
      @NgModule({  
       imports: [BrowserModule, FormsModule, NguiReactModule],  
       declarations: [AppComponent],  
       bootstrap: [ AppComponent ]  
      })  
      export class AppModule { }  
    
For full example, please check out app directory to see the example of
  • app.module.ts
  • and app.component.ts

Example Usage

hello.ts

 class Hello extends React.Component {  
  render() {  
   return <div>Hello {this.props.name}</div>;  
  }  
 }  

my-app.ts

 import { Component, ViewChild } from '@angular/core';  
 import { Hello } from "./hello"; // This is a react component  
 @Component({  
  selector: 'my-app',  
  template: `  
   <ngui-react   
    [reactComponent]="Hello"  
    [reactProps]="{name:'angular2 react wrapper'}">  
   </ngui-react>  


Note: Special thanks to ng2-ui

Contact: allenhwkim@gmail.com

Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
bower-videogular-analytics

bower-videogular-analytics

September 07, 2018
Videogular analytics plugin repository for distribution on bower.

Install

Install Videogular analytics plugin with Bower:
bower install videogular-angulartics

Install Videogular

Install Videogular with Bower:
bower install videogular

Install themes

Install Videogular themes with Bower:
bower install videogular-themes-default

Install plugins

Install Videogular plugins with Bower:
bower install videogular-controls
bower install videogular-overlay-play
bower install videogular-poster

Documentation

It's available on Videogular's project Wiki.

License

The MIT License (MIT)

Note: Special thanks to Videogular
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
bower-videogular-ima-ads

bower-videogular-ima-ads

August 30, 2018
Videogular ima-ads plugin repository for distribution on bower.

Install

Install Videogular ima-ads plugin with Bower:
 bower install videogular-ima-ads  

You must add this script to your head tag:
 <script type='text/javascript'>  
      var googletag = googletag || {};  
      googletag.cmd = googletag.cmd || [];  
      (function() {  
           var gads = document.createElement('script');  
           gads.async = true; gads.type = 'text/javascript';  
           gads.src = 'http://www.googletagservices.com/tag/js/gpt.js';  
           var node = document.getElementsByTagName('script')[0];  
           node.parentNode.insertBefore(gads, node);  
      })();  
 </script>  
For more info about how to use IMA ads visit Google's IMA ads website.

Install Videogular

Install Videogular with Bower:
 bower install videogular  

Install Videogular themes

Install Videogular themes with Bower:
 bower install videogular-themes-default  

Install Videogular plugins

Install Videogular plugins with Bower:
 bower install videogular-buffering  
 bower install videogular-overlay-play  
 bower install videogular-controls  

Documentation

It's available on Videogular's project Wiki.

License

The MIT License (MIT)
Note: Special thanks to Videogular
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
coconspirators

coconspirators

July 05, 2018
:telephone_receiver: Microservice framework for RabbitMQ written in TypeScript

Description

coconspirators is a microservice framework for RabbitMQ written in TypeScript. Under the hood it uses qmqp.node, the battle-tested AMQP client, to communicate with RabbitMQ and has best-practices baked in. Features include:
  • Simple API for subscribing, publish and replying
  • DI Friendly
  • TypeScript First

 

Install

 npm i coconspirators --S  

Building

 npm run build  

Usage

 import { Queue, AmqpQueue, AmqpClient } from 'coconspirators';  
 export class AmqpServer {  
  connection: Promise<any>;  
  constructor(public client: AmqpClient, logger: Logger) {  
   this.connection = this.client.connect();  
   client.on('connected', () => console.log('connected!'));  
   client.on('disconnected', () => console.log('disconnected!'));  
  }  
 }  
 interface ZooMessage {  
  animal: string;  
 }  
 @Queue({  
  name: 'health'  
  contentType: 'application/json'  
 })  
 export class HealthQueue extends AmqpQueue<ZooMessage> {  
  constructor(client: AmqpClient) { super(client); }  
 }  
 export class HealthChecker {  
  constructor(queue: HealthQueue) {  
   this.queue.publish({ hi: true });  
   this.queue.subscribe((message: ZooMessage) => {  
    console.log('message', message);  
   })  
  }  
 }  

Credits

ngx-datatable is a Swimlane open-source project; we believe in giving back to the open-source community by sharing some of the projects we build for our application. Swimlane is an automated cyber security operations and incident response platform that enables cyber security teams to leverage threat intelligence, speed up incident response and automate security operations.

Note: Special thanks to Swimlane

Contact: info@swimlane.com

Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
@ngrx/notify

@ngrx/notify

June 27, 2018

Web Notifications Powered by RxJS for Angular 2

Easily create and handle desktop notifications in Angular 2

Installation

Install @ngrx/notify from npm:

npm install @ngrx/notify --save

Setup the providers, optionally providing global notification options:

import { NOTIFY_PROVIDERS, NOTIFY_GLOBAL_OPTIONS } from '@ngrx/notify';

bootstrap(App, [
  NOTIFY_PROVIDERS,
  { provide: NOTIFY_GLOBAL_OPTIONS, multi: true, useValue: { /* global options here */ } }
])
 

Usage

Requesting Notification Permission

Before creating notifications, you must resolve the app's notification permission:
class AppComponent {
  constructor(notify: Notify) {
    notify.requestPermission().subscribe(permission => {
      if (permission) {
        // continue
      }
    });
  }
}
 

Creating a Notification

To create a notification observable, call the open() method with a title and optional config. The notification will be opened when you subscribe to the observable and will close after you unsubscribe from it. The observable will emit the instance of the notification every time it is clicked on:

notify.open('Hello world!', options)
  // Automatically close the notification after 5 seconds
  .takeUntil(Observable.timer(5000))
  // Close the notification after it has been clicked once
  .take(1)
  .subscribe(notification => {

  });

See the documentation on MDN for available options.

 
ngx-modialog

ngx-modialog

June 09, 2018

ngx-modialog (previously `angular2-modal`)

This project is looking for a new maintainer, see [#414](https://github.com/shlomiassaf/ngx-modialog/issues/414) for details.

ngx-modialog version 5.x.x works with angular 5.x.x

IMPORTANT - V4 BREAKING CHANGE:

Version 4.x.x contains some breaking changes, please see the [CHANGELOG](./CHANGELOG.md)

Library has been renamed from version 3.0.2

Modal / Dialog implementation for angular. - Easy to use API via Fluent API Presets (alert, prompt, confirm) - Can render Component's, TemplateRef's and literal string - Extendable via plugins. - Easy to use typescript modal.alert() .title('Hello World') .body('In Angular') .open(); Available plugins: - Bootstrap (3 & 4) - [Vex 3 & 4](http://github.hubspot.com/vex/docs/welcome/)

Install

bash npm install ngx-modialog

Basic plunker playground (bootstrap plugin):

ngx-modialog @ 4.x.x

http://plnkr.co/edit/lV7zsw7Yqossgs9JOfQU?p=preview

ngx-modialog @ 3.x.x

http://plnkr.co/edit/2ppVYl517GI1Byv8vVbG?p=preview

Quick start

**In your application root module definition add `ModalModule` and the plugin you want to use:** We will use the bootstrap plugin (`BootstrapModalModule`) for this introduction. ```typescript import { ModalModule } from 'ngx-modialog'; import { BootstrapModalModule } from 'ngx-modialog/plugins/bootstrap'; // lots of code... @NgModule({ bootstrap: [ /* ... */ ], declarations: [ /* ... */ ], imports: [ /* ... */ ModalModule.forRoot(), BootstrapModalModule ], }) export class AppModule { /* lots of code... */ } ```

In any angular component or service inject the `Modal` service and open a modal:

typescript import { Component, ViewContainerRef } from '@angular/core'; import { Overlay } from 'ngx-modialog'; import { Modal } from 'ngx-modialog/plugins/bootstrap'; @Component({ selector: 'my-app', template: `<button (click)="onClick()">Alert</button>` }) export class AppComponent { constructor(public modal: Modal) { } onClick() { const dialogRef = this.modal.alert() .size('lg') .showClose(true) .title('A simple Alert style modal window') .body(` <h4>Alert is a classic (title/body/footer) 1 button modal window that does not block.</h4> <b>Configuration:</b> <ul> <li>Non blocking (click anywhere outside to dismiss)</li> <li>Size large</li> <li>Dismissed with default keyboard key (ESC)</li> <li>Close wth button click</li> <li>HTML content</li> </ul>`) .open(); dialogRef.result .then( result => alert(`The result is: ${result}`) ); } } If you are using **ngx-modialog** version 3.X.X or below, `open()` returned a promise so replace the last 2 lines with: typescript dialogRef .then( dialogRef => { dialogRef.result.then( result => alert(`The result is: ${result}`); }); We are using the `alert()` method, one of 3 (prompt, confirm)) fluent-api methods we call `drop-ins` We then use the `result` property to wait for the modal closing event. **Notes:** - Fluent API methods (drop-ins) are pre-configured (presets) methods that allow easy configuration and execution, you can create custom presets - see the demo application. - For more control use the `open()` method, which is used by all drop in's internally. - We import the `Modal` service from the plugin and not from the root library. Import from the root should work but being explicit allow using multiple plugins. ## Demo App The Demo application is a full implementation of the library with the native plugins. View it at [shlomiassaf.github.io/ngx-modialog](http://shlomiassaf.github.io/ngx-modialog/) The demo application is [part of this repository](https://github.com/shlomiassaf/ngx-modialog/tree/master/src/demo/app) and it is a great place to learn by example.

Bootstrap / VEX features:

- Customizable with components, Presets and more... - Select cancel/quit key. - Cascading modals. - Element blocking. - Blocking / Non blocking modal. - Modal as a component, replace the content by supplying a custom component. The demo application comes with a [dynamic modal generator](http://shlomiassaf.github.io/ngx-modialog#/bootstrap-demo/customizeModals) for the **Boostrap** plugin ## Plugins Plugins serve as a concrete UI implementation for a modal. It can be an implementation for a known library (e.g: bootstrap) or something completely unique While `ngx-modialog` has some built in plugins it is also possible to use external plugins from NPM, if someone decide to build one. > Built a plugin? I would love to know :) # Known bugs ### The dialog closes when removing the target DOM element in a click event ref [issue#111](https://github.com/shlomiassaf/ngx-modialog/issues/111) To avoid this problem use `event.stopPropagation();` or put the element removal inside a `setTimeout` call # HELP WANTED! As a sole author I find it difficult to maintain multiple open source projects. As a result it is hard for me to replay rapidly to requests/help/etc... If you would like to contribute, please contact me, the community will thank you. You can contribute via: - Implementing features & Bug fixes - Documentation (Extremely important) - Issue management
ngSocketIO

ngSocketIO

February 22, 2018
Socket.IO module for AngularJS

Requirements

  • AngularJS 1.0.5+
  • Socket.IO 0.9.16

Installing

Simply download either ng-socket-io or ng-socket-io.min.js from the build folder and add it to your web application. Just make sure it's included after the AngularJS script.

Usage

  1. Add the socket-io module as a dependency in your AngularJS app;
  2. Inject the socket factory wherever you need to use Socket.IO;
  3. You're done!

Example

 <script src="angular.js"></script>  
 <script src="ng-socket-io.js"></script>  
 <script>  
   var myApp = angular.module('myApp', ['socket-io']);  
   myApp.controller('MyCtrl', function($scope, socket) {  
     // Listening to an event  
     socket.on('someEvent', function(data) {  
       $scope.data = data;  
     });  
     // Raising an event  
     $scope.raise = function(message) {        
       socket.emit('otherEvent', message);  
     };  
   });  
 </script>  

Cancelling a subscription automatically on scope destruction

If you want to unsubscribe from an event automatically on scope destruction, just call bindTo passing the current scope:
 socket.on('someEvent', function(data) {  
 ...   
 }).bindTo($scope);  

Note: Special thanks to Michael Benford
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
ngTagsInput

ngTagsInput

February 18, 2018
Tags input directive for AngularJS. Check out the ngTagsInput website for more information.

Requirements

  • AngularJS 1.3+
  • A modern browser (Chrome 31+, Firefox 29+, Safari 7+, Opera 12+, IE 10+)

Installing

All files are available from a variety of sources. Choose the one that best fits your needs:
You can also grab the latest build generated by Travis. It's fully functional and may contain new features and bugfixes not yet published to the services listed above.
Now all you have to do is add the scripts to your application. Just make sure the ng-tags-input.js file is inserted after the angular.js script:
 <script src="angular.js"></script>  
 <script src="ng-tags-input.js"></script>  
 <link rel="stylesheet" type="text/css" href="ng-tags-input.css">  

Usage

  1. Add the ngTagsInput module as a dependency in your AngularJS app;
  2. Add the custom element <tags-input> to the HTML file where you want to use an input tag control and bind it to a property of your model. That property, if it exists, must be an array of objects and each object must have a property named text containing the tag text;
  3. Set up the options that make sense to your application;
  4. Enable autocomplete, if you want to use it, by adding the directive <auto-complete> inside the <tags-input> tag, and bind it to a function of your model. That function must return either an array of objects or a promise that eventually resolves to an array of objects (same rule from step 2 applies here);
  5. Customize the CSS classes, if you want to.
  6. You're done!
Note: There's a more detailed getting started guide on the ngTagsInput website.

Example

 <html>  
 <head>  
   <script src="angular.min.js"></script>  
   <script src="ng-tags-input.min.js"></script>  
   <link rel="stylesheet" type="text/css" href="ng-tags-input.min.css">  
   <script>  
     angular.module('myApp', ['ngTagsInput'])  
       .controller('MyCtrl', function($scope, $http) {  
         $scope.tags = [  
           { text: 'just' },  
           { text: 'some' },  
           { text: 'cool' },  
           { text: 'tags' }  
         ];  
         $scope.loadTags = function(query) {  
            return $http.get('/tags?query=' + query);  
         };  
       });  
   </script>  
 </head>  
 <body ng-app="myApp" ng-controller="MyCtrl">  
   <tags-input ng-model="tags">  
     <auto-complete source="loadTags($query)"></auto-complete>  
   </tags-input>  
 </body>  
 </html>  

Options

Check out the documentation page for a detailed view of all available options.

Demo

You can see the directive in action in the demo page.

Contributing

Before posting an issue or sending a pull request, make sure to read the CONTRIBUTING file.

License

See the LICENSE file.

Changelog

See the CHANGELOG page.

Alternatives

The following are some alternatives to ngTagsInput you may want to check out:
  • angular-tags: Pure AngularJS tagging widget with typeahead support courtesy of ui-bootstrap
  • angular-tagger: Pure Angular autocomplete with tags, no jQuery
  • jsTag: Open source project for editing tags (aka tokenizer) based on AngularJS
  • bootstrap-tagsinput: jQuery plugin providing a Twitter Bootstrap user interface for managing tags (provides Angular support)

Latest build


Note: Special thanks to Michael Benford
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
textAngular

textAngular

February 15, 2018
A radically powerful Text-Editor/Wysiwyg editor for Angular.js! Create multiple editor instances, two-way-bind HTML content, watch editors for changes and more!

 

How to Use:

  1. Include textAngular.js in your project, alternatively grab all this code and throw it in your "directives.js" module file.
  2. Include textAngular in your main app module.
  3. Create an element of some kind. (div, whatever, doesn't matter)
  4. Add the text-angular directive to it.
  5. Add a text-angular-name="<YOUR TEXT EDITOR NAME>" directive to the element, as well.
  6. Create a textAngularOpts object and bind it to your local scope in the controller you want controlling textAngular It should look something like:
  1. If you want all editors to have individual settings: Proceed to 2. Otherwise go to 3.
  2. Create the textAngularEditors property manually (it will get created regardless, if you choose not to apply individual settings).
  3. Then add to it, a new property with the name of your editor you chose earlier. For instance, if it was "coolMonkeyMan" it will look like this:
  1. Globally inherited settings for each editor or individual settings? Either way you'll need to supply some options!

Global Options

html <STRING> the default html to show in the editor on load (also will be the property to watch for HTML changes!!!)
toolbar <ARRAY of OBJECTS> holds the toolbar items to configure, more on that later
disableStyle <BOOLEAN> disable all styles on this editor
theme <OBJECT of OBJECTS> holds the theme objects, more on that later

Setting up the Toolbar

Add tools to the toolbar like:

Note

If you want to use ultra-sweet icons in the menu (like I did in the example) make sure to include fontAwesome!
And then use the proper syntax for the titles i,e <i class='icon-<icon name>'></i>
Get it at: www.bootstrapcdn.com/#fontawesome

Toolbar Options

title <STRING> Can be an angular express, html, or text. Use this to add icons to each tool i,e <i class='icon-code'></i>
name <STRING> the command, the tool name, has to be one of the following: html <- this one is used to toggle the html view, so i'd probably keep it ;-) h1 h2 h3 p pre ul ol quote undo redo b justifyLeft justifyRight justifyCenter i clear insertImage insertHtml createLink 

Theming textAngular

Every piece of textAngular has a specific class you can grab and style in CSS. However, you can also use the theme object to specify styling. Each property takes a normal, jQuery-like CSS property object. Heres an example :

Theme Options

editor <OBJECT> the actual editor element
toolbar <OBJECT> the toolbar wrapper
toolbarItems <OBJECT> each toolbar item
insertForm <OBJECT> the form that holds the insert stuff
insertFormBtn <OBJECT> the button that submits the insert stuff

How to get the Editor Html

To actually get the model (watch or bind), simply follow this model:
textAngularOpts.textAngularEditors.<YOUR EDITORS NAME>.html
so to bind the expression:
or to $watch for changes:

Issues?

textAngular uses execCommand for the rich-text functionalty. That being said, its still a fairly experimental browser feature-set, and may not behave the same in all browsers. I've tested in FF, chrome and IE10 and its works as expected. If you find something, please let me know. Throw me a message, or submit a issue request!


Note: Special thanks to Austin Anderson
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
angular-loading-bar

angular-loading-bar

February 02, 2018
The idea is simple: Add a loading bar / progress bar whenever an XHR request goes out in angular. Multiple requests within the same time period get bundled together such that each response increments the progress bar by the appropriate amount.
This is mostly cool because you simply include it in your app, and it works. There's no complicated setup, and no need to maintain the state of the loading bar; it's all handled automatically by the interceptor.

Requirements: AngularJS 1.2+

File Size: 2.4Kb minified, 0.5Kb gzipped

Usage:

  1. include the loading bar as a dependency for your app. If you want animations, include ngAnimate as well. note: ngAnimate is optional
     angular.module('myApp', ['angular-loading-bar', 'ngAnimate'])  
    
  2. include the supplied JS and CSS file (or create your own CSS to override defaults).
     <link rel='stylesheet' href='build/loading-bar.min.css' type='text/css' media='all' />  
     <script type='text/javascript' src='build/loading-bar.min.js'></script>  
    
  3. That's it -- you're done!

via bower:

 $ bower install angular-loading-bar  

via npm:

 $ npm install angular-loading-bar  

via CDN:

  <link rel='stylesheet' href='//cdnjs.cloudflare.com/ajax/libs/angular-loading-bar/0.9.0/loading-bar.min.css' type='text/css' media='all' />  
  <script type='text/javascript' src='//cdnjs.cloudflare.com/ajax/libs/angular-loading-bar/0.9.0/loading-bar.min.js'></script>  

Why I created this

There are a couple projects similar to this out there, but none were ideal for me. All implementations I've seen require that you maintain state on behalf of the loading bar. In other words, you're setting the value of the loading/progress bar manually from potentially many different locations. This becomes complicated when you have a very large application with several services all making independent XHR requests. It becomes even more complicated if you want these services to be loosly coupled.
Additionally, Angular was created as a highly testable framework, so it pains me to see Angular modules without tests. That is not the case here as this loading bar ships with 100% code coverage.
Goals for this project:
  1. Make it automatic
  2. Unit tests, 100% coverage
  3. Must work well with ngAnimate
  4. Must be styled via external CSS (not inline)
  5. No jQuery dependencies

Configuration

Turn the spinner on or off:

The insertion of the spinner can be controlled through configuration. It's on by default, but if you'd like to turn it off, simply configure the service:
 angular.module('myApp', ['angular-loading-bar'])  
  .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {  
   cfpLoadingBarProvider.includeSpinner = false;  
  }])  

Turn the loading bar on or off:

Like the spinner configuration above, the loading bar can also be turned off for cases where you only want the spinner:
 angular.module('myApp', ['angular-loading-bar'])  
  .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {  
   cfpLoadingBarProvider.includeBar = false;  
  }])  

Customize the template:

If you'd like to replace the default HTML template you can configure it by providing inline HTML as a string:
 angular.module('myApp', ['angular-loading-bar'])  
  .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {  
   cfpLoadingBarProvider.spinnerTemplate = '<div><span class="fa fa-spinner">Loading...</div>';  
  }])  

Position the template:

If you'd like to position the loadingBar or spinner, provide a CSS selector to the element you'd like the template injected into. The default is the



element:
 angular.module('myApp', ['angular-loading-bar'])  
  .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {  
   cfpLoadingBarProvider.parentSelector = '#loading-bar-container';  
   cfpLoadingBarProvider.spinnerTemplate = '<div><span class="fa fa-spinner">Custom Loading Message...</div>';  
  }])  

 <div id="loading-bar-container"></div>  
Also keep in mind you'll likely want to change the CSS to reflect it's new position, so you'll need to override the default CSS:
 #loading-bar .bar {  
  position: relative;  
 }  

Latency Threshold

By default, the loading bar will only display after it has been waiting for a response for over 100ms. This helps keep things feeling snappy, and avoids the annoyingness of showing a loading bar every few seconds on really chatty applications. This threshold is totally configurable:
 angular.module('myApp', ['angular-loading-bar'])  
  .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {  
   cfpLoadingBarProvider.latencyThreshold = 500;  
  }])  

Ignoring particular XHR requests:

The loading bar can also be forced to ignore certain requests, for example, when long-polling or periodically sending debugging information back to the server.
 // ignore a particular $http GET:  
 $http.get('/status', {  
  ignoreLoadingBar: true  
 });  
 // ignore a particular $http POST. Note: POST and GET have different  
 // method signatures:  
 $http.post('/save', data, {  
  ignoreLoadingBar: true  
 });  

 // ignore particular $resource requests:  
 .factory('Restaurant', function($resource) {  
  return $resource('/api/restaurant/:id', {id: '@id'}, {  
   query: {  
    method: 'GET',  
    isArray: true,  
    ignoreLoadingBar: true  
   }  
  });  
 });  

How it works:

This library is split into two modules, an $http interceptor, and a service:

Interceptor
The interceptor simply listens for all outgoing XHR requests, and then instructs the loadingBar service to start, stop, and increment accordingly. There is no public API for the interceptor. It can be used stand-alone by including cfp.loadingBarInterceptor as a dependency for your module.

Service
The service is responsible for the presentation of the loading bar. It injects the loading bar into the DOM, adjusts the width whenever set() is called, and complete()s the whole show by removing the loading bar from the DOM.

Service API (advanced usage)

Under normal circumstances you won't need to use this. However, if you wish to use the loading bar without the interceptor, you can do that as well. Simply include the loading bar service as a dependency instead of the main angular-loading-bar module:

 angular.module('myApp', ['cfp.loadingBar'])  

 cfpLoadingBar.start();  
 // will insert the loading bar into the DOM, and display its progress at 1%.  
 // It will automatically call `inc()` repeatedly to give the illusion that the page load is progressing.  
 cfpLoadingBar.inc();  
 // increments the loading bar by a random amount.  
 // It is important to note that the auto incrementing will begin to slow down as  
 // the progress increases. This is to prevent the loading bar from appearing  
 // completed (or almost complete) before the XHR request has responded.  
 cfpLoadingBar.set(0.3) // Set the loading bar to 30%  
 cfpLoadingBar.status() // Returns the loading bar's progress.  
 // -> 0.3  
 cfpLoadingBar.complete()  
 // Set the loading bar's progress to 100%, and then remove it from the DOM.  

Events

The loading bar broadcasts the following events over $rootScope allowing further customization:

cfpLoadingBar:loading triggered upon each XHR request that is not already cached

cfpLoadingBar:loaded triggered each time an XHR request recieves a response (either successful or error)

cfpLoadingBar:started triggered once upon the first XHR request. Will trigger again if another request goes out after cfpLoadingBar:completed has triggered.

cfpLoadingBar:completed triggered once when the all XHR requests have returned (either successfully or not)

Credits:

Credit goes to rstacruz for his excellent nProgress.

Note: Special thanks to Wes Cruver
Contact: chieffancypants@gmail.com
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
angular-http-auth

angular-http-auth

February 01, 2018
This is the implementation of the concept described in Authentication in AngularJS (or similar) based application.
There are releases for both AngularJS 1.0.x and 1.2.x, see releases.
Launch demo here or switch to gh-pages branch for source code of the demo.

Usage

  • Install via bower: bower install --save angular-http-auth
  • ...or via npm: npm install --save angular-http-auth
  • Include as a dependency in your app: angular.module('myApp', ['http-auth-interceptor'])

Manual

This module installs $http interceptor and provides the authService.

The $http interceptor does the following: the configuration object (this is the requested URL, payload and parameters) of every HTTP 401 response is buffered and everytime it happens, the event:auth-loginRequired message is broadcasted from $rootScope.

The authService has only 2 methods: loginConfirmed() and loginCancelled().
You are responsible to invoke loginConfirmed() after user logs in. You may optionally pass in a data argument to this method which will be passed on to the loginConfirmed $broadcast. This may be useful, for example if you need to pass through details of the user that was logged in. The authService will then retry all the requests previously failed due to HTTP 401 response.
You are responsible to invoke loginCancelled() when authentication has been invalidated. You may optionally pass in a data argument to this method which will be passed on to the loginCancelled $broadcast. The authService will cancel all pending requests previously failed and buffered due to HTTP 401 response.
In the event that a requested resource returns an HTTP 403 response (i.e. the user is authenticated but not authorized to access the resource), the user's request is discarded and the event:auth-forbidden message is broadcast from $rootScope.

Ignoring the 401 interceptor

Sometimes you might not want the interceptor to intercept a request even if one returns 401 or 403. In a case like this you can add ignoreAuthModule: true to the request config. A common use case for this would be, for example, a login request which returns 401 if the login credentials are invalid.

Typical use case:

  • somewhere (some service or controller) the: $http(...).then(function(response) { do-something-with-response }) is invoked,
  • the response of that requests is a HTTP 401,
  • http-auth-interceptor captures the initial request and broadcasts event:auth-loginRequired,
  • your application intercepts this to e.g. show a login dialog:
  • DO NOT REDIRECT anywhere (you can hide your forms), just show login dialog
  • once your application figures out the authentication is OK, call: authService.loginConfirmed(),
  • your initial failed request will now be retried and when proper response is finally received, the function(response) {do-something-with-response} will fire,
  • your application will continue as nothing had happened.

Sending data to listeners:

You can supply additional data to observers across your application who are listening for event:auth-loginConfirmed and event:auth-loginCancelled:
  $scope.$on('event:auth-loginConfirmed', function(event, data){  
       $rootScope.isLoggedin = true;  
       $log.log(data)  
  });  
  $scope.$on('event:auth-loginCancelled', function(event, data){  
   $rootScope.isLoggedin = false;  
   $log.log(data)  
  });  
Use the authService.loginConfirmed([data]) and authService.loginCancelled([data]) methods to emit data with your login and logout events.

Updating $http(config):

Successful login means that the previous request are ready to be fired again, however now that login has occurred certain aspects of the previous requests might need to be modified on the fly. This is particularly important in a token based authentication scheme where an authorization token should be added to the header.
The loginConfirmed method supports the injection of an Updater function that will apply changes to the http config object.
 authService.loginConfirmed([data], [Updater-Function])  
 //application of tokens to previously fired requests:  
 var token = response.token;  
 authService.loginConfirmed('success', function(config){  
  config.headers["Authorization"] = token;  
  return config;  
 })  
The initial failed request will now be retried, all queued http requests will be recalculated using the Updater-Function.
It is also possible to stop specific request from being retried, by returning false from the Updater-Function:
 authService.loginConfirmed('success', function(config){  
  if (shouldSkipRetryOnSuccess(config))  
   return false;  
  return config;  
 })  

Note: Special thanks to Witold Szczerba
Contact: witoldsz.dev@gmail.com
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
angular2-multiselect-dropdown

angular2-multiselect-dropdown

December 25, 2017
Angular 2 multiselect dropdown component for web applications. Easy to integrate and use.

Table of Contents

1. Getting Started
2. Installation
3. Usage
4. Templates
5. Template Driven Forms support
6. Reactive Forms support
7. Settings configuration
8. Callbacks and events

Getting Started

Installation

  • The Mutiselect Dropdown package is published on the npm Registry.
  • Install the package : npm install angular2-multiselect-dropdown
  • Once installed import AngularMultiSelectModule from the installed package into your module as follows:

Usage

Import AngularMultiSelectModule into NgModule in app.module.ts
 import { AngularMultiSelectModule } from 'angular2-multiselect-dropdown/angular2-multiselect-dropdown';  
 @NgModule({  
  // ...  
  imports: [  
   AngularMultiSelectModule,  
  ]  
  // ...  
 })  
Declare the component data variables and options in your component where you want to consume the dropdown component.
 import { Component, OnInit } from '@angular/core';  
 export class AppComponent implements OnInit {  
   dropdownList = [];  
   selectedItems = [];  
   dropdownSettings = {};  
   ngOnInit(){  
     this.dropdownList = [  
                {"id":1,"itemName":"India"},  
                {"id":2,"itemName":"Singapore"},  
                {"id":3,"itemName":"Australia"},  
                {"id":4,"itemName":"Canada"},  
                {"id":5,"itemName":"South Korea"},  
                {"id":6,"itemName":"Germany"},  
                {"id":7,"itemName":"France"},  
                {"id":8,"itemName":"Russia"},  
                {"id":9,"itemName":"Italy"},  
                {"id":10,"itemName":"Sweden"}  
               ];  
     this.selectedItems = [  
                 {"id":2,"itemName":"Singapore"},  
                 {"id":3,"itemName":"Australia"},  
                 {"id":4,"itemName":"Canada"},  
                 {"id":5,"itemName":"South Korea"}  
               ];  
     this.dropdownSettings = {   
                  singleSelection: false,   
                  text:"Select Countries",  
                  selectAllText:'Select All',  
                  unSelectAllText:'UnSelect All',  
                  enableSearchFilter: true,  
                  classes:"myclass custom-class"  
                 };        
   }  
   onItemSelect(item:any){  
     console.log(item);  
     console.log(this.selectedItems);  
   }  
   OnItemDeSelect(item:any){  
     console.log(item);  
     console.log(this.selectedItems);  
   }  
   onSelectAll(items: any){  
     console.log(items);  
   }  
   onDeSelectAll(items: any){  
     console.log(items);  
   }  
 }  
Add the following component tag in you template
 <angular2-multiselect [data]="dropdownList" [(ngModel)]="selectedItems"   
   [settings]="dropdownSettings"   
   (onSelect)="onItemSelect($event)"   
   (onDeSelect)="OnItemDeSelect($event)"  
   (onSelectAll)="onSelectAll($event)"  
   (onDeSelectAll)="onDeSelectAll($event)"></angular2-multiselect>  

Template - For custom html of menu item

 <angular2-multiselect [data]="dropdownList" [(ngModel)]="selectedItems" [settings]="dropdownSettings">  
  <c-item>  
      <ng-template let-item="item">  
       <label style="color: #333;min-width: 150px;">{{item.itemName}}</label>  
       <img [src]="item.image" style="width: 30px; border: 1px solid #efefef;margin-right: 20px;" />  
       <label>Capital - {{item.capital}}</label>  
      </ng-template>  
  </c-item>    
 </angular2-multiselect>  

Template Driven Forms support

 <form (ngSubmit)="onSubmit()" #loginForm="ngForm" style="border: 1px solid #ccc; padding: 10px;">  
     <div class="form-group">  
       <label for="name">Skills</label>  
       <angular2-multiselect [data]="itemList" [(ngModel)]="formModel.skills"   
                  [settings]="settings"   
                  (onSelect)="onItemSelect($event)"  
                  (onDeSelect)="OnItemDeSelect($event)"   
                  (onSelectAll)="onSelectAll($event)"   
                  (onDeSelectAll)="onDeSelectAll($event)" name="skills">  
       </angular2-multiselect>  
     </div>  
 </form>  

 formModel = {  
     name: '',  
     email: 'ascasc@aa.com',  
     skills: [{ "id": 1, "itemName": "Angular" }]  
   };  

Reactive Forms support

 <form [formGroup]="userForm" novalidate style="border: 1px solid #ccc; padding: 10px;">  
     <div class="form-group">  
       <label for="name">Skills</label>  
       <angular2-multiselect [data]="itemList" [(ngModel)]="selectedItems"   
                  [settings]="settings"   
                  (onSelect)="onItemSelect($event)"  
                  (onDeSelect)="OnItemDeSelect($event)"   
                  (onSelectAll)="onSelectAll($event)"   
                  (onDeSelectAll)="onDeSelectAll($event)" formControlName="skills">  
       </angular2-multiselect>  
     </div>  
 </form>  

 userForm: FormGroup;  
 this.userForm = this.fb.group({  
       name: '',  
       email: ['', Validators.required],  
       skills: [[], Validators.required]  
     });  

Settings

The following list of settings are supported by the component. Configure the settings to meet your requirement.
Setting Type Description Default Value
singleSelection Boolean To set the dropdown for single item selection only. false
text String Text to be show in the dropdown, when no items are selected. 'Select'
enableCheckAll Boolean Enable the option to select all items in list false
selectAllText String Text to display as the label of select all option Select All
unSelectAllText String Text to display as the label of unSelect option UnSelect All
enableSearchFilter Boolean Enable filter option for the list. false
maxHeight Number Set maximum height of the dropdown list in px. 300
badgeShowLimit Number Limit the number of badges/items to show in the input field. If not set will show all selected. All
classes String Custom classes to the dropdown component. Classes are added to the dropdown selector tag. To add multiple classes, the value should be space separated class names. ''
limitSelection Number Limit the selection of number of items from the dropdown list. Once the limit is reached, all unselected items gets disabled. none
disabled Boolean Disable the dropdown false
searchPlaceholderText String Custom text for the search placeholder text. Default value would be 'Search' 'Search'
groupBy String Name of the field by which the list should be grouped. none
searchAutofocus Boolean Autofocus search input field true

Callback Methods

  • onSelect - Return the selected item on selection. Example : (onSelect)="onItemSelect($event)"
  • onDeSelect - Return the un-selected item on un-selecting. Example : (onDeSelect)="OnItemDeSelect($event)"
  • onSelectAll - Return the list of all selected items. Example : (onSelectAll)="onSelectAll($event)"
  • onDeSelectAll - Returns an empty array. Example : (onDeSelectAll)="onDeSelectAll($event)"
  • onOpen - Callback method fired after the dropdown opens Example : (onOpen)="onOpen($event)"
  • onClose - Callback method, fired when the dropdown is closed Example : (onClose)="onClose($event)"

Note: Special thanks to Pradeep Terli
Contact: solomon.terli@gmail.com
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.
angular-cesium

angular-cesium

December 24, 2017
Create map based applications using cesium and angular2 components. Focusing on high performance with easy usage. Check out our Demo that contains small app built with angular-cesium.

Getting started

  • install angular-cesium:
     $ npm install --save angular-cesium
    
  • Angular cli

  • If you didn't installed Angular CLI yet:
     $ npm install -g @angular/cli
    
  • start new project:
     $ ng new PROJECT_NAME
    $ cd PROJECT_NAME
    
  • Import and add AngularCesiumModule to your app root module:
     import { AngularCesiumModule } from 'angular-cesium';
    // ....
    @NgModule({
     declarations: [],
     imports: [
      // ...
      AngularCesiumModule.forRoot()
     ],
     bootstrap: [AppComponent]
    })
    export class AppModule {
    }
    $ cd PROJECT_NAME
    
  • AngularCesiumModule configuration

  • The main module should be loaded with .forRoot() in order to make the module perform enhancements to Cesium, However, the module can be loaded with out calling forRoot().
  • .forRoot() excepts an optional option object of type ModuleConfiguration where every option can be toggled on or off. If no options object is passed, a default one will be used.
Cesium fixes / enhancements:
  • Fix entities shadowing bug - fixEntitiesShadows
Cesium configuration
In order to use cesium you must serve some assets from cesium package. The following configuration is for angular-cli projects, for webpack users try this.
  • install cesium via:
     $ npm install --save cesium
    
  • Add cesium assets, script and css in .angular-cli.json file:
     "assets": [ // ...
          { "glob": "**/*", "input": "../node_modules/cesium/Build/Cesium", "output": "./assets/cesium" }
         ],
        "styles": [ // ...
          "../node_modules/cesium/Build/Cesium/Widgets/widgets.css"
        ],
        "scripts": [ // ...
          "../node_modules/cesium/Build/Cesium/Cesium.js"
        ],
    
  • Add CESIUM_BASE_URL in main.ts file , before bootstraping:
      // ...
      window['CESIUM_BASE_URL'] = '/assets/cesium';
      platformBrowserDynamic().bootstrapModule(AppModule);
    
  • Add declare var Cesium; to typing.d.ts file.
  • You can configure cesium viewer style:
     // styles.css
    html, body, #cesiumContainer {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
    }
    $ cd PROJECT_NAME
    
  • Live long and prosper

Demo

  • You can try and learn about angular-cesium from our demo: http://www.angular-cesium.com ( most optimized as desktop application ).
  • The demo contains 2 examples
    • Real data: showing real planes using GraphQL to warp an exiting REST service.
    • Simulated data: displaying planes data and sending using Socket.io.
        $ git clone https://github.com/TGFTech/angular-cesium.git
      $ cd angular-cesium
      $ yarn
      $ yarn server
      $ yarn start
      $ open http://localhost:8080
      

Basic example

  • In your HTML file :
      <ac-map>  
        <ac-layer acFor="let plane of planes$" [show]="showTracks" [context]="this">  
          <ac-billboard-desc props="{  
               image: plane.image,  
               position: plane.position  
              }">  
          </ac-billboard-desc>  
          <ac-label-desc props="{  
              position: plane.position,  
              text: plane.name  
          }">  
          </ac-label-desc>  
        </ac-layer>  
      </ac-map>  
    

  • ac-map creates the map
  • ac-layer component represent an array of entities that will be displayed on the map.
    • acFor attribute accepts an RxObserver planes$ , ac-layer will subscribe to the observer and will handle all updates for you.
  • Add descriptions components to determine which entity to render, in our example: ac-billboard and ac-label .
    • This example will render a billboard(icon) and label for each plane in the stream.
    • props accepts the same member options as cesium corresponding class. For example ac-billborad-desc accepts same members as cesium Billboard.

AC Layer

ac-layer is a directive which is meant to define a whole layer. In case you have previous knowledge about CesiumJs, you would notice that there are lots of map objects e.g. billboard, label, etc'. In the real world - we would like to merge all of this map objects into a single entity e.g. an airplane consists of a billboard(icon) and a label. Now, let's create a simple airplanes layer and go through it's definitions: First of all - the data source for a layer must be an RxJs stream. Second - every notification on the stream should be of type AcNotification:
 export class AcNotification {  
      id: number;  
      entity?: AcEntity;  
      actionType: ActionType;  
 }  
id - unique entity key, entity- the data itself for the entity, actionType- presents what happened to the entity. actionType can be one of those values:
 export enum ActionType {  
      ADD_UPDATE,  
      DELETE  
 }  
In case ADD_UPDATE is passed - the entity will be created or updated depending on if it exists or not. In case DELETE is passed - the entity will be removed from the map.
Now, assuming that each entity on this stream presents a plane, lets assume that each plane consists of this schema:
  • position - which presents the current plan position
  • name - which presents the plane name(to be presented on the map).
  • image - the PNG or whatever image you may like to use.
Now, Let's look at this piece of code:
 <ac-map>  
    <ac-layer acFor="let plane of planes$" [context]="this" [store]="true">  
      <ac-billboard-desc props="{  
           image: plane.image,  
           position: plane.position  
          }">  
      </ac-billboard-desc>  
      <ac-label-desc props="{  
          position: plane.position,  
          text: plane.name,  
          fillColor: getColor(plane)  
      }">  
      </ac-label-desc>  
    </ac-layer>  
  </ac-map>  
  • ac-map - Is a directive which presents the map and create a new Cesium instance.
  • ac-layer - Is our current directive which presents a plan layer. Remember that the data source must be a stream? In our case the stream is planes$.
  • acFor - Is a directive which lets you decide how would you call a single plane(or a single entity on the stream) in order to write the relevant expressions inside the directive(we'll see this in a moment). It should be noticed that the format for acFor is: let {x} of {our stream}.
  • context - The context of the observable (planes$) and the cesium descriptions props (same context as getColor). Usually it will be the context of the component itself - this.
  • store - Default: false. Tells Ac-Layer if it should store the entities it receives. The entities stored in the Ac-Layer store are extends by notifications from the stream (planes$).The store is an <entity id, entity> map. This in an optional basic data store. You can you use any kind of third party data store (e.g. ngrx/store).
Now, after we have defined our layer and decided that each entity on the stream will be called plane, let's drill down into the definitions of how an entity should look.
  • ac-billboard-desc - which presents billboard from CesiumJs. This directive allows you to pass props(expressions) to this billboard. You may see that although we do pass props - we actually pass expressions that are based on the plane that we defined earlier. Actually we say: 'Dear angular-cesium, please create and manage a billboard using those expressions for each plane'. Now, when an entity is passed through the stream - based on it's id, actionType and entity - angular-cesium will know what to do. When passing data with the same id and actionType=ADD_UPDATE - the entity will be updated on the map for every message.
  • ac-label-desc - the same as ac-billboard-desc but just for labels. It should be mentioned that ac-billboard-desc & ac-label-desc are all exposing the same API as Cesium expose for each map-entity.
It is important to mention that angular-cesium doesn't duplicate the description component over the DOM for each different plane in $plane (as ngFor does).

why? because there is no reason to, cesium entities are drawn on the canvas map using javascript API i.e. entities aren't represented as HTML, by doing so we gain a major boost in performance.
After explaining a little bit about ac-layer we hope that you may see it's benefits:
  • Easily defining a layer
  • Easily add/update/remove entities - all you have to do is pass a message through the stream and angular-cesium will keep track of all the rest.
  • Readable code - when reading your html which describes your layer - it is pretty easy to understand how your layer would look.
  • Maintainable code.

Supported Entity types

ac-entity-desc vs ac-entity

  • ac-entity-desc component is used to describe how each entity / array of entities in a stream of entities, managed inside ac-layer, should be drawn.
  • ac-entity-primitive-desc component is the same as ac-entity-desc with the difference of using Primitives to render the graphics. It is more efficient than ac-entity-desc when drawing an updating entity.
  • ac-entity component is used to draw an entity directly on the map, and so, can be used directly under ac-map.

Entities API

  • All of the entity components are using a flatten Cesium Entities API.
  • e.g: ac-billboard props input accepts a JSON which can have all properties found in Cesium Entity (like position) plus all properties found in Cesium BillboardGraphics (like).
  • In AngularCesium, entities have a default height of 0 (except of Billboards and Labels). This as in line with Cesium docs. For some reason in Cesium itself, the default height is undefined which leads Cesium to use GroundPrimitive which is less efficient. As a result, if you want your entity to be more efficient, set height: 0 or any other value in the props.

Map Events

MapEventsManagerService is a util service for managing all the map events (Click, Mouse_up...), it expose easy API for entity selection, event priority management and adds custom events (drag and drop, long press).
Usage:
 @Component(...)  
 export class SomeComponent{  
  constructor(private eventManager: MapEventsManagerService){  
   // Input about the wanted event   
   const eventRegistration: EventRegistrationInput = {  
    event: CesiumEvent.LEFT_CLICK, // event type enum. [required!]  
    modifier: CesiumEventModifier.CTRL, // event modifier enum. [optional]  
    entityType: AcEntity, // raise event only if AcEntity is clicked. [optional]   
    priority: 0, // event priority, default 0 . [optional]  
    pick: PickOptions.PICK_FIRST // entity pick option, default PickOptions.NO_PICK. [optional]  
   };  
   const clickEvent = this.eventManager.register(eventRegistration).subscribe((result) => {  
      // The EventResult will contain:   
      // movement(screen location of the event), entities(your entities) , primitives( cesium primitives, like label,billboard...)  
         console.log('map click', result.movement, 'primitives:', result.primitives, 'entities', result.entities);  
        });  
  }   
 }  
In the example above we start listing to Click events. according to eventRegisration object.
  • eventManager.register()
    • Returns RxJs observer of type DisposableObservable<EventResult> that we can subsribe to.
    • To remove the event registration just do: resultObserver.dispose()
  • event: according to CesiumEvent enum. All cesium events are supported, includes additional events like DragNDrop and LongPress
  • entityType: it is possible to register to events on a specific entities types, e.g raise event only when TrackEntity is Clicked.
    • AcEntity is the base class for all angular-cesium entities, it is a part of AcNotification and is required for MapEventManager to work properly.
    • All entities should inherit from AcEntity
      e.g class TrackEntity extends AcEntity {}
  • Priority: by setting the priority you can register same events and only the one with the higher priority will be raised. For example lets say when you left_click on the map a context menu should appear but if you in a drag and drop state you want that left_click will raise a drop event only, you can achive this by setting different priority to each event.
  • PickOptions: according to the PickOptions enum, set the different strategies for picking entities on the map:
    • NO_PICK - will not pick entities
    • PICK_FIRST - first entity will be picked . use Cesium.scene.pick()
    • PICK_ONE - in case a few entities are picked plonter is resolved . use Cesium.scene.drillPick()
    • PICK_ALL - all entities are picked. use Cesium.scene.drillPick()
MapEventsManagerService is porivided by <ac-map/>, therefor has 2 possibilitis to reach it:
  • In any components under <ac-map/> hierarchy as seen in the example above (recomannded).
  • Using@viewChild and ac-map reference: acMapComponent.getMapEventManagerService() .
Checkout demo/app/components/event-test-layer/event-test-layer.component.ts for more examples.
All cesium map events run out side angular zone
Meaning that the the callback that you pass to map event manager will be executed outside of angular zone. That is because Cesium run outside of Angular zone in case for performance reasons , kind of ON_PUSH strategy.
For example if you update your html template for every map event and you want it to render, you should use ChangeDetectorRef or warp your function with NgZone.run()
 class MyComponent {  
  constructor(eventManager: MapEventsManagerService, ngZone: NgZone){  
    eventManager.register(eventRegistration).subscribe((result) => {  
      ngZone.run(()=>{  
        this.textShownInTheTemplateHtml = result.movment;  
      });   
     });  
  }  
 }  

Plonter

In case a two or more entities are in the same location and both are clicked you have a plonter (which entity should be picked?).
This is resolved according to the PickOptions that we pass to the event registration:
  • NO_PICK - non of the entities will be picked, you only interested in the map location.
  • PICK_FIRST - the first(upper) entity will be picked.
  • PICK_ALL - all entities are picked and returned.
  • PICK_ONE - only one should be picked, a context will appear allowing the client to choose which entity he wants, selected entity will be passed to the eventcall back.
angular-cesium comes with ac-default-plonter a basic implementation for the plonter context menu. showing a list of entities names to select from.
It is possible to create your own plonter context menu just take a look at ac-default-plonter implementation, and disable the default plonter:
 <ac-map [disableDefaultPlonter]="true"></ac-map>  

Map layers

With angular cesium you can define your map provider in a declarative way using ac-map-layer-provider :
  <ac-map-layer-provider *ngIf="appSettingsService.showMapLayer" [provider]="MapLayerProviderOptions.ArcGisMapServer"  
               [options]="{  
                 url : 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'  
               }">  
   </ac-map-layer-provider>  
  • All cesium imagery map layers are supported , defined with [provider] according to the MapLayerProviderOptions enum
  • Pass additional configuration to [options] . url is mandatory.
  • Support multi map layers, map ordering and map image layer configuration.
  • Check out usage example from our demo here

3d Tiles

 <ac-3d-tile-layer  
     *ngIf="appSettingsService.show3dtiles"  
     [options]="{  
      url: 'https://beta.cesium.com/api/assets/1461?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkYWJmM2MzNS02OWM5LTQ3OWItYjEyYS0xZmNlODM5ZDNkMTYiLCJpZCI6NDQsImFzc2V0cyI6WzE0NjFdLCJpYXQiOjE0OTkyNjQ3NDN9.vuR75SqPDKcggvUrG_vpx0Av02jdiAxnnB1fNf-9f7s'  
     }">  
   </ac-3d-tile-layer>  

Camera Keyboard Control Service

 this.keyboardControlService.setKeyboardControls({  
    W: { action: KeyboardAction.CAMERA_FORWARD },  
    S: { action: KeyboardAction.CAMERA_BACKWARD },  
    D: { action: KeyboardAction.CAMERA_RIGHT },  
    A: { action: KeyboardAction.CAMERA_LEFT },  
   },  

MapsManagerService

Angular Cesium extends cesium api and expose additional features, but if you want to use pure cesium api you can use MapsManagerService to receive cesium viewer or any other util service that was created by ac-map.
 class MyComp {  
 constructor(mapsManagerService: MapsManagerService)  
      const viewer = mapsManagerService.getMap().getCesiumViewer();  
      const mapEventManager = mapsManagerService.getMap().getMapEventsManager();  
      const cameraService = mapsManagerService.getMap().getCameraService();  
 }  

Geometry Editors

Part of AngularCesiumWidgetsModule are useful geometry editors tool:
Try running our demo for examples (uncomment the relevant components in demo-map.component.html).

Documents

Check out our api Docs
Note: Special thanks to TGFTech
Contact: tgftechinc@gmail.com
Disclaimer: The blog is created to share angular directives information to geek, curious Angular Developers.