Created
July 8, 2015 20:26
-
-
Save xogeny/fcbeba98b8d70dc5003a to your computer and use it in GitHub Desktop.
My canonical directive structure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <reference path="../typings/angularjs/angular.d.ts" /> | |
// A canonical layout for defining angular directives in TypeScript | |
module ModuleForDirective { | |
// Defines what we expect to find in $scope. This mainly the stuff | |
// mapped in the scope: attribute of the directive, but it could | |
// include stuff inherited into $scope as well... | |
interface Scope extends ng.IScope { | |
// Stuff defined in { scope: { ... } } (attrs on directive) | |
// Stuff inherited in $scope | |
} | |
class Controller { | |
// View properties (stuff we compute from $scope) | |
// ... | |
static $inject = ["$scope", ...]; | |
constructor(private $scope: Scope, ...) { | |
// Assign watches on stuff in { scope: { ... } } | |
$scope.$watch('prop1', (nv: TypeOfProp1) => { | |
this.computeView(nv, $scope.prop2) | |
}, true); | |
$scope.$watch('prop2', (nv: TypeOfProp2) => { | |
this.computeView($scope.prop1, nv) | |
}, true); | |
} | |
// Any methods you want to be able to invoke on the controller (from the template) | |
// (generally, these are to manipulate values on $scope are to evaluate | |
// computed properties. | |
// This method is used to recompute view properties based on values in $scope | |
// This assumes all members of the Controller class depend on all members in $scope. | |
// If they don't, then multiple functions can be defined to more efficiently compute | |
// subsets based on changes (dependencies) in $scope. | |
private computeView(prop1: TypeOfProp1, prop2: TypeOfProp2) { | |
// Update setup related view quantities | |
// (compute values of members of this class based on p1 and p2 from $scope) | |
// this._____ = f(prop1, prop2); | |
} | |
} | |
export function Directive(): ng.IDirective { | |
return { | |
restrict: "E", // Can only be an Element | |
replace: false, | |
controller: Controller, | |
controllerAs: "cname", | |
template: ..., | |
scope: { | |
prop1: '=', | |
prop2: '=', | |
... | |
// Should match inputs to Scope interface | |
}, | |
// Fancy stuff often requires a link: field to be defined as well | |
}; | |
} | |
Directive.$inject = []; // Any dependencies to inject in call to Directive | |
} | |
angular.module("ModuleName").directive(ModuleForDirective.Directive) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I don't see anything bad here. Here's what we have at Picnic:
Filename
fooDirective.ts
Filename
fooDirective.html
Note: I'm using external modules