npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

angular-ts

v0.3.0

Published

An approach to using ES6 classes in Angular JS 1.x with Typescript

Downloads

11

Readme

Angular TS

NPM Version License

This library provides ngRegister, a modified version of Michael Browmley's register.js.

Example

angular-ts allows us to declare classes and register them as angular components. Here is a summary

import { ngRegister } from 'angular-ts';

class MyAngularComponent {
  constructor(dependency1, dependency2) {
    this.dependency1 = dependency1;
    this.dependency2 = dependency2;
    // stuff happens here
  }

  someMethods() {
    this.dependency1.doThatThing();
    this.dependency2.doThatOtherThing();
    // more stuff here
  }
}
MyAngularComponent.$inject = ['dependency1', 'dependency2'];

ngRegister('app')
  .controller('MyController', MyAngularComponent)
  .service('myService', MyAngularComponent1)
  .provider('myOtherService', MyAngularComponent2)
  .factory('myFactory', MyAngularComponent3)
  .directive('myDirective', MyAngularComponent4);

or if you prefer to use the dependencies without declaring them you may use the inject function.

import { ngRegister, inject } from 'angular-ts';

class MyAngularComponent {
  constructor(...args) {
    inject(this, args);
    // stuff happens here
  }

  someMethods() {
    this.dependency1.doThatThing();
    this.dependency2.doThatOtherThing();
    // more stuff here
  }
}
inject(MyAngularComponent, ['dependency1', 'dependency2']);

ngRegister('app')
  .controller('MyController', MyAngularComponent)
  .service('myService', MyAngularComponent1)
  .provider('myOtherService', MyAngularComponent2)
  .factory('myFactory', MyAngularComponent3)
  .directive('myDirective', MyAngularComponent4);

If you are using the experimentalDecorators option in the typescript compiler you may wish to use the Inject decorator. This allows us to write the previous example as

import { ngRegister, inject } from 'angular-ts';

@Inject(['dependency1', 'dependency2'])
class MyAngularComponent {
  constructor(...args) {
    inject(this, args);
    // stuff happens here
  }

  someMethods() {
    this.dependency1.doThatThing();
    // more stuff here
  }
}

ngRegister('app')
  .controller('MyController', MyAngularComponent)
  .service('myService', MyAngularComponent1)
  .provider('myOtherService', MyAngularComponent2)
  .factory('myFactory', MyAngularComponent3)
  .directive('myDirective', MyAngularComponent4);

Directives

The angular-1.x directives usually have a lot of options that you can provide. At some point it can get annoying writing something like

import { Inject } from 'angular-ts';

@Inject(['a', 'b'])
class MyDirective {
  // Directive options
  template: string;
  requires: string[];
  // ... other directive options

  // Injected Dependencies
  a: any;
  b: any;

  constructor(...args: any[]) {
    inject(this, args);
    this.template = 'template goes here';
    this.requires = ['other directives'];
    // ...
    // and so on ...
  }

}

Instead, we may extend from Directive and skip declaring the directive options.

import { Directive, Inject } from 'angular-ts';

@Inject(['a', 'b'])
class MyDirective extends Directive {
  // Injected Dependencies
  a: any;
  b: any;

  constructor(...args: any[]) {
    super(args);
    this.template = 'template goes here';
    this.requires = ['other directives'];
    // ...
    // and so on ...
  }
}

This tells the typescript compiler that the class already declares template, requires and all the other options that a directive provides. Note that all a Directive does is call inject during initialization as it has been previously done, so do not forget to call the super constructor with args.

For other examples see example/js/ex-directive.js. One thing to mention here is that compile, link, preLink and postLink are optional methods. Please note however that if postLink and link are both declared then only the postLink method will be called. These two methods should be one and the same so only declare one.

Component

Angular 1.5 introduces components. These were made to make migration to Angular 2 a bit easier. To migrate we can write components as follows:

import {
  Inject,
  inject,
  NgComponent,
  NgOnInit,
  NgPostLink,
} from 'angular-ts';

@NgComponent({
  selector: 'ex-component',
  template: '<div>This is the template</div>',
})
@Inject([
  '$element',
])
class ExComponent implements NgOnInit, NgPostLink {
  $element: JQuery;

  constructor(...args: any[]) {
    inject(this, args);
  }

  $onInit(): void {
    this.$element.css('color', 'red');
  }

  $postLink(): void {
    console.log('This is the postLink hook, analogous to the ngAfterViewInit and ngAfterContentInit hooks in Angular 2');
  }
}

export {
  ExComponent,
};

To register the component we don't have to provide the selector name since this is already defined in the NgComponent decorator.

import { ExComponent } from 'ExComponent'

ngRegister('app')
  .component(ExComponent);

See https://docs.angularjs.org/guide/component for more information on components and https://docs.angularjs.org/api/ng/service/$compile#life-cycle-hooks for an in depth explanation on the life cycle hooks.

Mixins

If you need to make a component that is a Directive and extends from some other class you may use the mix function provided by this library. For instance:

import { Directive, Inject, mix } from 'angular-ts';

class OtherClass {
  constructor(a, b, c) {
    this.a = a;
    this.b = b;
    this.c = c;
  }

  getA() {
    return this.a;
  }
}

@Inject([
  'dep1',
  'dep2',
  // and so on ...
])
class SomeController extends mix(Directive, OtherClass) {
  constructor(...args) {
    super([Directive, args], [OtherClass, 1, 2, 3]);
  }

  doSomething() {
    console.log('Calling OtherClass method: ', this.getA());
    console.log('Using dependencies: ', this.dep1.somemethod);
  }
}

NOTE: Do not use instanceof when using mix. Instead use the isinstance function provided by the library.

API

inject(clazz: any, injectables: (string | any)[]): void

Can be used after a class declaration to inject its dependencies as well as inside the constructor to attach the dependencies to an instance of the class.

import { inject } from 'angular-ts';

class A {
  constructor(...args: any[]) {
    inject(this, args);
  }
}
inject(A, ['a', 'b']);

Note that when using after the declaration we must provide the class object and not an instance as we have done in the constructor.

Inject(args: string[]): Function

A decorator to replace using inject after the class declaration. This allows us to see the dependencies that an angular component uses right in the class declaration.

import { Inject, inject } from 'angular-ts';

@Inject(['a', 'b'])
class A {
  constructor(...args: any[]) {
    inject(this, args);
  }
}

class Directive

Utility class which provides the following interface:

interface Directive {
    controller?: any;
    controllerAs?: string;
    bindToController?: boolean | Object;
    multiElement?: boolean;
    name?: string;
    priority?: number;
    replace?: boolean;
    require?: string | string[] | {
        [controller: string]: string;
    };
    restrict?: string;
    scope?: boolean | Object;
    template?: string | Function;
    templateNamespace?: string;
    templateUrl?: string | Function;
    terminal?: boolean;
    transclude?: boolean | string | {
        [slot: string]: string;
    };
    compile?(templateElement: ng.IAugmentedJQuery, templateAttributes: ng.IAttributes, transclude?: ng.ITranscludeFunction): void;
    link?(scope: ng.IScope, instanceElement: ng.IAugmentedJQuery, instanceAttributes: ng.IAttributes, controller: any, transclude: ng.ITranscludeFunction): void;
    preLink?(scope: ng.IScope, instanceElement: ng.IAugmentedJQuery, instanceAttributes: ng.IAttributes, controller: any, transclude: ng.ITranscludeFunction): void;
    postLink?(scope: ng.IScope, instanceElement: ng.IAugmentedJQuery, instanceAttributes: ng.IAttributes, controller: any, transclude: ng.ITranscludeFunction): void;
}

Any angular component extending from Directive will need to call super with the constructors arguments.

import { Directive, Inject } from 'angular-ts';

@Inject(['a', 'b'])
class A extends Directive {
  constructor(...args: any[]) {
    super(args);
  }
}

ngRegister(appName: string, dependencies?: string[]): NgRegister

Provides a wrapper for angular.module, we can create a brand new angular module by providing the module dependencies or get the angular module by omitting them. This will return an instance of NgRegister which provides all the methods an angular module has: controller, directive, service, etc. To obtain the non-wrapped angular module use the method module.

import { ngRegister } from 'angular-ts';

const app = ngRegister('mymodule', [])
  .controller('ctrl', Ctr)
  .directive('dir', Dir)
  // ...
  .module();

mix(...mixins: any[]): typeof IMixin

Allows us to create a custom class which combines all the methods of the specified mixins.

class A {
  a: number;
  constructor(a: number) {
    this.a = a;
  }
  printA() { console.log(this.a); }
}

class B {
  b: number;
  constructor(b: number) {
    this.b = b;
  }
  printB() { console.log(this.b); }
}

class C extends mix(A, B) {
  c: number;
  constructor(a: number, b: number, c: number) {
    super([A, a], [B, b]);
    this.c = c;
  }
  printC() { console.log('c'); }
}

const obj: C = new C(1, 2, 3);
obj.printA();
obj.printB();
obj.printC();

isinstance(object: any, classinfo: any): boolean

Used to check if an object is an instance of a given class. We may provide an array in the second argument if we want to check if an object is an instance of any of classes in the array.

loadNgModule(callback: Function): any[],

Utility function to help lazy load angular modules. To use it first require the module with webpacks bundle loader:

const lazyBundleCallback = require('bundle?lazy!./realative/path/to/angular/module');

Then on the router load it on a resolve, for instance:

.state('somestate', {
  url: 'someurl/',
  views: {...},
  resolve: {
     lazyLoadModule: loadNgModule(lazyBundleCallback),
  }
});

You may call lazyLoadModule anything you want, this is just a function that will resolve.

Note: You will need to register ocLazyLoad with the app in order for this to work.