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

ng-classes

v1.0.2

Published

ES6, ES7 and TS base classes for AngularJS units

Downloads

13

Readme

ng-classes

Base classes for object-oriented Angular 1.x units, tailored with DI in mind.

Come in ES2015 (ES6), ES2016 (ES7) and TypeScript flavours.

Flavours

ES2015 (ES6)

import { NgBase } from 'ng-classes';

or

let ngClasses = require('ng-classes');
let NgBase = ngClasses.NgBase;

ES2016 (ES7)

import { NgBase } from 'ng-classes/es7';

TypeScript

import { NgBase } from 'ng-classes/ts';

Compatibility

NgProvider and NgDirective classes use ES5 getters/setters (IE9+) to substitute methods in children.

NgProvider uses Function.prototype.bind (IE9+) to supply its instance to NgProviderInstance.

ES2016/TS decorators call for ES5 getters/setters.

factory uses Object.getOwnPropertyNames and Object.getOwnPropertyDescriptor (IE9+), also Object.getPrototypeOf and Object.setPrototypeOf (IE11) for able-bodied support of static property inheritance.

Dependency injection

@inject decorator (ES2016/TS)

Can be used to annotate classes and class members.

import { inject, NgBase } from 'ng-classes';

@inject('$logProvider')
class JoeProvider extends NgBase {
	constructor(...deps) {
		super(...deps);

		this.$.$logProvider.…;
	}

	@inject('$log', '$q')
	$get($log, $q) { … }
}

$inject static property

class JoeProvider extends NgBase {
	static $inject = ['$logProvider'];
	…
}

Class instantiation

@factory decorator (ES2016/TS)

Allows to feed classes to Angular units that expect factory functions. Unicontroller and service may benefit from this, too, in the case of instantiation problems (applicable to pre-1.5 Angular with native classes).

Replaces a class with wrapper function that instantiates it. Wrapper properties are prototypically inherited from class if Object.setPrototypeOf is supported, otherwise they are copied (all properties from the class and enumerable properties from its parents). This may cause inheritance issues in older JS engines, particularly if static properties are changed after class declaration, or parent classes have non-enumerable static properties.

All children classes of a decorated class will inherit from wrapper function, not a class itself.

Should be used in the first place, before @inject and other class decorators. The decorators are executed in reverse order of their appearance, a factory wrapper and not original class will be decorated otherwise.

import { factory, inject, NgBase, NgDirective } from 'ng-classes';

class JoeAbstractDirective extends NgDirective {}

Object.defineProperty(JoeAbstractDirective, 'nonEnumerableStaticProp', {
	value: 'May not be available as JoeDirective.nonEnumerableStaticProp'
});

// Preferably a final class
@factory
@inject('$log')
class JoeDirective extends JoeAbstractDirective {
	static staticProp = 'Available as JoeDirective.staticProp and this.constructor.staticProp';

	constructor(...deps) {
		super(...deps);

		// this.constructor !== JoeDirective
 
		this.constructor.lateStaticProp = 'May not be available as JoeDirective.lateStaticProp';
	}
}

// Commonly does not require a factory wrapper
class JoeService extends NgBase { … }

angular.module('average', [])
	.service('JoeService', JoeService)
	.directive('joe', JoeDirective);

factory function

The same function can be also used as a helper but has no inherent side effects of @factory decorator.

…
angular.module('average', [])
	.service('JoeService', JoeService)
	.directive(factory(JoeDirective));

$factory static method

Provides the same functionality for base classes as factory function.

…
angular.module('average', [])
	.service('JoeService', JoeService)
	.directive(JoeDirective.$factory());

ng-classified extension

Base classes have $classify property and are compatible with ng-classified, no additional instantiation measures are necessary.

import { NgBase, NgDirective } from 'ng-classes';
import { ngClassifiedModule } from 'ng-classified';

class JoeService extends NgBase { … }

class JoeDirective extends NgDirective { … }

angular.module('average', [ngClassifiedModule])
	.service('JoeService', JoeService)
	.directive('joe', JoeDirective);

Classes

ng-classes

ng-classes~NgBase

Base class for Angular units. Child classes are supposed to be supplied into most places that feature Angular DI - controllers, config and run blocks, factory and service services, etc.

Kind: inner class of ng-classes

new NgBase(...deps)

| Param | Type | Description | | --- | --- | --- | | ...deps | * | Injected dependencies |

NgBase.$inject : Array.<string>

Annotates class constructor for Angular injector.

Kind: static property of NgBase
Default: []
Access: public

NgBase.$classify

Provides support for ng-classified.

Kind: static constant of NgBase
Default: true
Access: public

NgBase.$factory() ⇒ function

Creates an annotated class wrapper which is supplied to Angular injector.

Kind: static method of NgBase
Returns: function - Factory function that returns a new class instance.
Access: public

ng-classes~NgProvider ⇐ NgBase

Base class for Angular service providers. Accepts a child of NgProviderInstance class as $get value to be instantiated as service instance.

Kind: inner class of ng-classes
Extends: NgBase

ngProvider.$get ⇒ function

$get getter/setter. Dispathes factory function from/to _$get.

Kind: instance property of NgProvider
Access: public

ng-classes~NgProviderInstance ⇐ NgBase

Base class for Angular provider service instances

Kind: inner class of ng-classes
Extends: NgBase

new NgProviderInstance(provider, ...deps)

| Param | Type | Description | | --- | --- | --- | | provider | NgProvider | Provider class instance. | | ...deps | * | Injected dependencies. |

ng-classes~NgDirective ⇐ NgBase

Base class for Angular directives

Kind: inner class of ng-classes
Extends: NgBase

ngDirective.restrict : string

Restricts directive declaration, forces the defaults in Angular 1.2.x for consistency.

Kind: instance property of NgDirective
Default: "EA"
Access: public

ngDirective.compile ⇒ function

compile getter/setter. Puts original function to _compileFn and returns _compile wrapper.

Kind: instance property of NgDirective
Access: public

ng-classes~NgTemplate ⇐ NgBase

Base class for Angular component templates

Kind: inner class of ng-classes
Extends: NgBase

ngTemplate.toString() ⇒ string

Shadows Object.prototype.toString method. Affects object conversion when a string is expected (DOM assignments, String.prototype methods).

Kind: instance method of NgTemplate
Access: public

ngTemplate.valueOf() ⇒ string

Shadows Object.prototype.valueOf method. Affects type conversion (string operators, non-strict equality).

Kind: instance method of NgTemplate
Access: public

Usage

As shown in this demo app,

<body>
  <joe-directive>Directive can be DI-powered class</joe-directive>
  <joe-component>Component's template function can be DI-powered class as well</joe-component>
</body>

bootstrap.js

import 'angular';
import appModule from './app';

angular.bootstrap(document.body, [appModule]);

app.js

import joeDirectiveModule from './joe-directive';
import joeComponentModule from './joe-component';

export default angular.module('average', [joeDirectiveModule, joeComponentModule])
  .name;

joe-provider-complex.js

import { factory, inject, NgProvider, NgProviderInstance } from 'ng-classes';

// Decorators are executed in reverse order of their appearance.
// @factory should come first.
@factory
@inject('$logProvider')
export class JoeProviderComplex extends NgProvider {
  debug(flag) {
    return this.$.$logProvider.debugEnabled(flag);
  }
  
  $get = JoeProviderComplexInstance;
}

@inject('$log')
export class JoeProviderComplexInstance extends NgProviderInstance {
  logOnly(flag) {
    // Provider object, passed to constructor and available as this.$provider
    this.$provider.debug(!flag);

    // Injected $log, passed to constructor and available as this.$.$log    
    let { $log } = this.$;
    $log.debug('complex provider debug');
    $log.log('complex provider log');
    
    return 'Logging with joeProviderComplex instance' + (flag && ' with no debugging');
  }
}

export default angular.module('average.joeProviderComplex', [])
  .provider('joeProviderComplex', JoeProviderComplex)
  .name;

joe-provider-basic.js

import { factory, inject, NgBase } from 'ng-classes';

// Provider can be defined with NgBase instead of NgProvider/NgProviderInstance
export class JoeProviderBasic extends NgBase {
  log(logService) {
    logService.log('basic provider log');
  }

  // and having a single class for provider and instance can be tedious
  @inject('$log')
  $get($log) {
    this.log($log);

    // but provider instance result can return any value,
    // no toString/valueOf shadowing in class is required.
    return 'Logging with joeProviderBasic instance';
  };
}

export default angular.module('average.joeProviderBasic', [])
  // 'factory' helper function is the alternative to '@factory' decorator.
  .provider('joeProviderBasic', factory(JoeProviderBasic))
  .name;

joe-controller.js

import { factory, inject, NgBase } from 'ng-classes';
import joeProviderComplexModule from './joe-provider-complex';
import joeProviderBasicModule from './joe-provider-basic';

// No @factory is necessary for instantiated units.
@inject('joeProviderComplex', 'joeProviderBasic')
export class JoeController extends NgBase {
  constructor(...deps) {
    super(...deps);

    this.messageBasic = this.$.joeProviderBasic;
    this.messageComplex = this.$.joeProviderComplex.logOnly(true);
  }
}

export default angular.module('average.joeController', [joeProviderComplexModule, joeProviderBasicModule])
  .controller('JoeController', JoeController)
  .name;

joe-directive.js

import { factory, inject, NgDirective } from 'ng-classes';
import joeControllerModule from './joe-controller';

export class JoeDirective extends NgDirective {
  template = `
<div>    
  <h1>joe-directive</h1>
  <h2 ng-transclude></h2>
  <p></p>
  <p></p>
</div>
  `;

  transclude = true;
  
  controller = 'JoeController';
  
  controllerAs = 'vm';

  compile = (element) => {
    this.messageCompile = 'compile';
  }

  preLink = (scope, element, attrs, ctrl) => {
    ctrl.messagePreLink = 'pre-link';
  }
  
  link = (scope, element, attrs, ctrl) => {
    ctrl.messagePostLink = 'post-link';

    let text = [this.messageCompile, ctrl.messagePreLink, ctrl.messagePostLink].join(', ');
    text += ' functions can coexist on DDO';
    
    element.append(angular.element('<p>').text(text))
  }
}

export default angular.module('average.joeDirective', [joeControllerModule])
  // $factory() method does the same job as '@factory' decorator and 'factory' helper function
  .directive('joeDirective', JoeDirective.$factory())
  .name;

joe-component.js

import { factory, inject, NgBase, NgTemplate } from 'ng-classes';

export class JoeComponent {
  template = JoeComponentTemplate.$factory();
}

@inject('$element')
export class JoeComponentTemplate extends NgTemplate {
  constructor(...deps) {
    super(...deps);

    let text = this.$.$element.text();

 	// The instance is converted to $template value with shadowed toString() and valueOf().
    this.$template = `
<div>    
  <h1>joe-component</h1>
  <h2>${text}</h2>
</div>
    `;
  }
}

export default angular.module('average.joeComponent', [])
  // Components don't do DI, the class can be just 'new'ed.
  .component('joeComponent', new JoeComponent)
  .name;