Skip to content

Latest commit

History

43 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

ng-next

Ng-next is a simple and elegant way to use Angular 1.x with ES6 / ES7. It provides an expressive syntax to maintain the simplicity and readability of your code.

  • Decorators for angular & ui-router
  • Async / Await integration to make it compatible with angular's $digest cycle
  • Monkey patch for $scope.$watchCollection to work with ES6 iterables (Set / Map / Symbol.iterator)

Requirements

  • Angular 1.x

Note: In order to use Angular UI-Router specific decorators, you need to install Angular UI-Router first.

Installation

NPM

Ng-next is available on npm

npm install --save ng-next

Angular Module

Make sure you define your angular module before

Then simply import the package like this:

import"ng-next"

Ng-next relies on ng-app to fetch your angular module.
Alternatively you can define it on the config object.

Babel & Decorators

For the full list of ECMAScript 2015 features, please refer to the Babel Documentation.

If you want to use decorators please install Babel support for decoratos

Async / Await

Making asynchronous http requests was until now a bit of a hassle. Ng-next provides therefore an elegant and convenient way to achieve the same result. Ng-next makes use of the ES6 async / await functions.

asyncgetUsers(){this.user=awaitthis.UserService.index();}

You don't have to manually call the $rootScope.$digest() after every asynchronous http requests you make. This is achieved by injecting proxies into the default Promise class, which is used by async / await. The proxies get injected into Promise the first time you call import "ng-next". Magic!

Debounce $digest

Be aware of the amount of async / await or Promise.then statements you use in your project. High usage can cause slight performance issues. In this case you can limit all $rootScope.$digest() calls by setting a minimum duration that has to pass before $rootScope gets $digested again.

import{config}from"ng-next"config.DEBOUNCE_DIGEST_MILLIS=[millis]//Debounce for [millis]config.DEBOUNCE_DIGEST_MILLIS=false//Disable debounce

$scope.$watchCollection

Ng-next monkey patches $scope.$watchCollection of every scope to make it compatible with any iterable object.
With this technique you can use ng-repeat and similiar directives with a Set or any object that has a [Symbol.iterator] method.

import{Controller}from"ng-next"
@ControllerexportclassListController{list=newSet(["1","2","3","4","5"])[Symbol.iterator](){returnlist[Symbol.iterator]();}}//Html<divng-controller="ListController as listCtrl"><h1>Iterate over Set</h1><h2ng-repeat="item in listCtrl.list">{{ item }}</h2><h1>Iterate over controller</h1><h2ng-repeat="item in listCtrl">{{ item }}</h2></div>

Decorators

Angular configuration decorators

  • @Controller
  • @Service
  • @Component
  • @Directive
  • @Filter
  • @Config / @Run

Utility decorators

  • @Inject
  • @Init
  • @Destroy
  • @On
  • @Watch
  • @WatchCollection
  • @Debounce

Other decorators

  • @State
  • @Alias
  • @View
  • @Bind

Angular configuration decorators

@Controller

import{Controller}from"ng-next"
@ControllerexportclassFooController{
@Inject$http;}
@Controller("BarController")//Minify safeexportclassBarController{
@Inject$rootScope;}

@Service

import{Service}from"ng-next"
@ServiceexportclassFooService{}
@Service("BarService")//Minify safeexportclassBarService{}

@Component

@Component is placed directly on top of its controller!

import{Component,View,Alias,Bind}from"ng-next"/** * Component with decorators */
@Component("bar")//<bar></bar> Same as @Component({ name : "bar" })
@Alias("barCtrl")
@View("<h1>{{ barCtrl.foo }}</h1>")exportclassBarComponent{
@Bind("=")foo;constructor(){console.log(this.foo);}}/** * More old-scool component. * The object given into the decorator is used as directive configuration * You may use every property a directive can have */
@Component({name : "foo",template : "<h1>{{ fooCtrl.bar }}</h1>"bind : {bar : "="},as : "fooCtrl"})//<foo> </foo>exportclassFooComponent{constructor(){console.log(this.bar);}}

@Directive

import{Directive}from"ng-next"
@Directive("foo")//<div foo> </div>exportclassFooDirective{restrict="AE"scope={bar : "="}link(...){}}

@Filter

import{Filter}from"ng-next"exportclassFilters{/** * @ngInject */
@Filter//uses method name as filter nameupper($http){return(string)=>string.toUpperCase()}/** * @ngInject */
@Filter("lower")lower($rootScope){return(string)=>string.toLowerCase()}}}

@Config / @Run

import{Config,Run}from"ng-next"exportclassConfiguration{/** * @ngInject */
@RunrunSomething($rootScope){return(string)=>string.toUpperCase()}/** * @ngInject */
@ConfigconfigureSomething($httpProvider){//Config method}}

Utility decorators

Those decorators should only be used on controllers and services. For services ng-next will use the $rootScope as the scope for @On, @Watch etc.

import{Inject,Controller,Init,Destroy,On,Watch,WatchCollection,Debounce}
@ControllerexportclassMainController{/** * Directly inject the angular http service */
@Inject$http;/** * Directly inject the controller $scope */
@Inject$scope;/** * Inject the $rootScope under an alias */
@Inject("$rootScope")baseScope;/** * A random property */property="Hello World";/** * A random array */array=["1","hello","red"];
@Init//You cannot use await in constructors, so @Init is perfect for thatasyncinit(){letresponse=awaitthis.$http.get("....");//Do init stuff}
@DestroycleanUp(){//Cleanup when the controller / its scope gets destroyed}/** * With @On you can listen to any event you can with $scope.$on */
@On("$stateChangeSuccess")stateChanged(event){console.log("state changed",event)}/** * With @Watch you can listen to any property as you would with $scope.$watch, but  * its evaluateed on the controller instead of the scope */
@Watch("property")stateChanged(newValue,oldValue){console.log(`Property changed from ${oldValue} to ${newValue}`)}/** * With @WatchCollection you can listen to any property as you would with $scope.$watchCollection, but  * its evaluateed on the controller instead of the scope */
@WatchCollection("array")stateChanged(newValue,oldValue){console.log(`Array changed from ${oldValue} to ${newValue}`)}/** * @Debounce will debounce the method for the given amount of millis */
@Debounce(100)oftenCalledMethod(){//I get executed after i wasn't called for 100 milliseconds}}

Other decorators

@State

The @State decorator defines a state for the common ui-router plugin and sets the class
its on top of as controller.
You can combine it with @View / @Alias or configure the state as you're used to.

import{State,Alias,View}
@State({name : "user",url : "/user",default : true// Default state})
@View("/views/user.html")
@Alias("userCtrl")exportclassUserController{//State controller}

@Alias

Sets the controllerAs property of an @Component or @State

import{Alias,State,Component}
@State(...)
@Alias("userCtrl")exportclassUserController{ ... }
@Component("user")
@Alias("userCtrl")exportclassUserComponent{ ... }

@View

Sets the template / templateUrl property of an @Component or @State, if the string contains a "<" it will be treated as the HTML template, otherwise it will be considered as the path to the HTML template.

import{View,State,Component}
@State(...)
@View("/views/user.html")exportclassUserController{ ... }
@Component("user")
@View("<h1>Hello</h1>")exportclassUserComponent{ ... }

@Bind

Defines a property / attribute which should be bound with the related component. In this case the user component.

import{Bind,Component,View}
@Component("user")
@View("<h1>{{ $ctrl.name }}</h1>")exportclassUserComponent{/** * If the html is <user name="Dude"></user> then * this property is "Dude" */
@Bind("@")name;}

Info

This little library is pretty new and under active development. Please report bugs and improvements :)

License

The ng-next library is open-sourced software licensed under the MIT License.

About

Ng-next provides a simple way to use angular 1.x with ES6 / ES7

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages