Angular

Angular

 - $q / $http after each step run $digest

 - a lot of excess code for component declaration

   Angular classy help to make more cleaner

 

 - no default CLI commands

   Yeoman

 

 - no default way to build application

   Yeoman / Requirejs

 

 - directive attributes

Angular + require

define(function(require){

  var Module = require('../../module'),
      Url = require('../src/url');


    // do something
});

Angular + require plugins

define(function(require){

  var Module = require('module!@'),
      Url = require('src!url'),
      controller = require('controller!demo');


    // do something
});
define(function(require){
    
    require('controller!demo');
    require('controller!home');

    require('src!url');
    require('src!ui/loading-overlay');

    require('directive!hello-world');
});

Files that require all project scripts

Angular + require

NOT OK!1

Angular components

angular.module('application')
    .controller('application.demo', [
            '$scope', 'foo', 'bar',
          function($scope, foo, bar) {

              $scope.visible = true;        

              $scope.click = function() {};

              function calc() {
                
              }


              $scope.export = function() {

              }   
          }
    ]);





Controller

In green box - attr and methods that available in view.

Angular templates

<div ng-if="isVisible">
  <date-picker
    ng-model="model"
    range="true"
    min-date="min_value"
    max-date="max_value"
    highlite-range="config.highlite"
    ng-show="isVisible"></datepicker>

  <comple-select
    ng-model="model"
    items="items"
    normalize-names="normalizers.names"
    ng-select-link="hierarchy.getItems()"
    in-popup="true"></complex-select>
</div>

A lot of logic in templates

Angular templates

<div ng-controller="app.demo">
  <div ng-if="isVisible" id="toggle">
    <select

      ng-model="model"

      ng-options="item.id as item.name for item in items">
    </select>
  </div>
</div>

If model type is not object or array - its changes will be visible only at div#toggle scope. Because ng-if creates additional scope

Angular controllers

angular.module('application')
    .controller('application.demo', ['$scope',
      function($scope) {

        function click() {}
        function save() {}

        /**
         * $scope methods and variables
         */
        angular.extend($scope, {
          click: click,
          save: save
        });

        function initWatchers() {
          $scope.$watch('foo', function(value){});
        }

        function init() {
          initWatchers();
        }


        init();
      }
    ]);

Code standart for default angular controllers

ngx

import { Controller } from 'ngx';

class Demo { }

Controller('application.demo')
 .route('/')
 .src(Demo);
  angular.module('application')
    .controller('application.demo', ['$scope',
      function($scope) {

      }
    ]);

    angualr.module('application')
      .config(['$routeProvider',
        function ($routeProvider) {
          $routeProvider.when('/', {
            controller: 'application.demo',
            templateUrl: 'demo.html'
            reloadOnSearch: false
          });
        }
      ]);

Angular

Controller

ngx

import { Directive } from 'ngx';

class Controller {}

Directive('hello-world')
  .scope({
    name: '='
  })
  .controller(Controller);
angular.module('application')
  .directive('helloWorld', [
    function(){

      return {
        restrict: 'E',
        replace: true,
        templateUrl: 
            '...../hello-world.html',
        scope: {
          'name': '='
        },
        controller: ['$scope', function($scope) {}]
      }
    }
  ]);

Angular

Directive

ngx directive

import { Directive } from 'ngx';

class Controller {}

Directive('hello-world')
  .scope({
    name: '='
  })
  .controller(Controller);

Available flow methods:

  • scope
  • defaults
  • controller
  • api
  • dependencies
  • template
  • templateUrl

If directives template is not defined - ngx will try to find template at same dir with same name - 'hello-world.html'

ngx directive api

import { Directive } from 'ngx';

class Controller {}

class HelloWorld {
  constructor($scope) {
    this.scope = $scope;
  }

  toggle() {
   this.scope.visible = !this.scope.visible;
  }

}

Directive('hello-world')
  .scope({
    name: '='
  })
  .api(HelloWorld)
  .controller(Controller);
import { Controller } from 'ngx';

class Demo extends Base {
  toggle() {

   this.api('hello-world').toggle();

  }
}

Controller('application.demo')
 .route('/')
 .src(Demo);

Directive

Controller

ngx directive api

import { Controller } from 'ngx';

class Demo extends Base {
  toggle() {

   this.api('hello-world.first').toggle();

  }
}

Controller('application.demo')
 .route('/')
 .src(Demo);

Controller

Template


<hello-world api-key="first"></hello-world>

<hello-world api-key="second"></hello-world>

ngx directive with ng-model

import { Directive } from 'ngx';

class Controller {}

Directive('hello-world')
 .controller(Controller)

 // name of local ng-model variable
 .model('localModel')

 // func call if local model changed
 // works with promises
 .validation(function() {});
 
<div>
 <switch ng-model="visible"></switch>
 <multi-select ng-model="localModel">
 </multi-select>
</div>
<hello-world ng-model="value"></hello-world>

hello-world.js

hello-world.html

template

ngx directive with ng-model

import { Directive } from 'ngx';

class Controller {}

Directive('hello-world')
 .controller(Controller)

 // name of local ng-model variable
 .model('localModel')

 // func call if local model changed
 // works with promises
 .validation(function() {});
 
angular.module('application')
  .directive('helloWorld', [
    function(){
      function validate() { ... }

      return {
        restrict: 'E',
        replace: true,
        require: 'ngModel',
        templateUrl: 'src/tpl/hello-world.html',
        scope: {
          'model': '=ngModel'
        },
        controller: ['$scope', function($scope) {}],
        link: function(scope, element, attrs, ngModel) {
          ngModel.$render = function() {          
            scope.localModel = ngModel.$viewValue;
          }
          scope.onChange = function(){
            var value = scope.localModel;
    
            if (validate(value)){
              ngModel.$setViewValue();
            }
          }
        }
      }
    }
  ]);

instead of 

ngx

Provide runtime flow:

 - Controller

 - Directive

 - Route

 - Factory

 

and other features

Provide node.js api for compiling.

npm install ngx
bower install ngx
var ngx = require('ngx');

Available from console:

 - init (proxy to enchup.init)

 - setup (proxy to enchup.setup)

 - create (proxy to enchup.create)

 - info (proxy to enchup.info)

 - build

ES6 source maps

Compatible with default angular application

import { Controller } from 'ngx';

class Scope {}


Controller('home.index')
    .route('/')
    .src(Scope);


// default angular controller
angular.module('application')
    .controller('home.demo', [function() {

         }
    ]);

ES6

Use traceur for compilation

About ES6

How we use ES6

  • Classes instead of $scope
  • ES6 Promises instead of $q 
  • Types (harmony proposal)

Types


import {context, promise} from 'structs';

class StatisticController {
 
 load(params:context):promise {
   // ....
 }
}
import { Tcomb as T } from 'tcomb';

var Filter = T.struct({
 value: T.list(T.Num),
 operation: T.enums('equal more less')
});

export var context = T.struct({
  id: T.Num,
  filters: T.list(Filter)
});

As structs and assertion we use tcomb

Could be used on dev env. On prod could be disabled when compiling without changes in code

var ngx = require('ngx');

var Instance = ngx({...});

Instance.setOptions({
    types: !!isDev
});

We dont use all experimental functions. We hope that when ES6 will release - we just remove builder and all will be OK :)

  • annotations
  • types
  • other not ES6 features
@Directive({
  selector: ['blink']
});
class Blink {
  constructor(element:Element, 
              options:Options,
              timeout: Timeout) {
   ...
  }
}

Thanx

valeriy.sorokobatko@gmail.com

Angular and ES6

By Valerii Sorokobatko