I am attempting change the way I am writing AngularJS apps from a plain-javascript to using TypeScript as a pre-processor.
I am struggling to reconcile the two approaches when it comes to scoped method calls.
For illustrative purposes, let's consider the common menu use-case; I wish to highlight a specific menu item which is currently displayed. The HTML template looks like this:
<ul class="nav navbar-nav">
...
<li ng-class="{active: isSelected('/page1')}"><a href="#/page1">Page 1</a></li>
...
</ul>
This anticipates a scoped function called isSelected. With old-school javascript coding, I' write this as:
$scope.isSelected = function(path) {
return $location.path().substr(0, path.length) == path;
}
This anonymous function declaration doesn't really seem to honor the more traditional class model of TypeScript. In typescript, I find myself tempted to write this:
export interface MenuScope extends ng.IScope {
isSelected(path: String): boolean;
}
export class MenuController {
location: ng.ILocationService;
scope: MenuScope;
constructor($scope: MenuScope, $location: ng.ILocationService) {
this.scope = $scope;
this.location = $location;
this.scope.isSelected = function(path) { return this.isSelected(path) }.bind(this);
}
isSelected(path: String): boolean {
return this.location.path().substr(0, path.length) == path;
}
}
In this case, isSelected belongs to the controller, rather than the scope. This seems sensible. However, the "link" between the scope and controller still relies on an anonymous method.
Even worse, I've had to explicitly bind the context of this to ensure I can write this.location to access the location service in the implementation of isSelected().
One of the benefits I am looking for from TypeScript is a clearer way of writing code. This indirection through a binded anonymous function seems to be the antithesis of this.
$scopewhereever possible.