How To bind data using TypeScript Controller & Angular Js
Solution 1:
I decided to add another answer describing more details how to create and use controller in TypeScript
and inject it into angularJS
.
This is extension of this Answer
How can I define my controller using TypeScript? Where we also have a working plunker
So having this directive:
export class CustomerSearchDirective implements ng.IDirective
{
public restrict: string = "E";
public replace: boolean = true;
public template: string = "<div>" +
"<input ng-model=\"SearchedValue\" />" +
"<button ng-click=\"Ctrl.Search()\" >Search</button>" +
"<p> for searched value <b>{{SearchedValue}}</b> " +
" we found: <i>{{FoundResult}}</i></p>" +
"</div>";
public controller: string = 'CustomerSearchCtrl';
public controllerAs: string = 'Ctrl';
public scope = {};
}
We can see, that we declared this directive to be available as Element. We also in-lined a template. This template is ready to bind SearchedValue
and call Action on our controller Ctrl.Search()
. We are saying what is the name of controller: 'CustomerSearchCtrl' and asking runtime to make it available as 'Ctrl' (conrollerAs:)
Finally we inject that object into angular module:
app.directive("customerSearch", [() => new CustomerSearch.CustomerSearchDirective()]);
We can use $scope
as ng.IScope
, but to have more typed access to it, we can create our own interface:
export interface ICustomerSearchScope extends ng.IScope
{
SearchedValue: string;
FoundResult: string;
Ctrl: CustomerSearchCtrl;
}
This way, we know, that we have string SearchedValue
and also other string FoundResult
. We also informed the application that Ctrl will be injected into that scope, and will be of type CustomerSearchCtrl
. And here comes that controller:
export class CustomerSearchCtrl
{
static $inject = ["$scope", "$http"];
constructor(protected $scope: CustomerSearch.ICustomerSearchScope,
protected $http: ng.IHttpService)
{
// todo
}
public Search(): void
{
this.$http
.get("data.json")
.then((response: ng.IHttpPromiseCallbackArg<any>) =>
{
var data = response.data;
this.$scope.FoundResult = data[this.$scope.SearchedValue]
|| data["Default"];
});
}
}
plus its registration into module
app.controller('CustomerSearchCtrl', CustomerSearch.CustomerSearchCtrl);
What is interesting on this controller? it has one public acton Search, which has access to all its membes via this.
, e.g. this.$http
. Because we instructed intellisense in VS that angular.d.ts type/interface
protected $http: ng.IHttpService
will be used, we can later easily access its methods. Similar is the type of returned value in .then()
.then((response: ng.IHttpPromiseCallbackArg<any>) => {...
which does contain data: {} of any type...
Hope it helps a bit, observe that all in action here
Solution 2:
There is one issue with your constructor and $inject
- these must fit together
// wrong
static $inject = ['$scope', '$http', '$templateCache'];
constructor (
private $http,
private $templateCache
){}
// should be
static $inject = ['$scope', '$http', '$templateCache'];
constructor (
private $scope,
private $http,
private $templateCache
){}
What happened in fact - all params were moved in the meaning, that
$http
was$scope
in fact, etc...
Simply, $inject
array MUST fit to constructor parameter list
BTW, that's why I had previously here: https://stackoverflow.com/a/30482388/1679310 suggested to use types in the declaration:
constructor(protected $scope: ICustomerScope,
protected $http: ng.IHttpService,
protected $templateCache: ng.ITemplateCacheService)
{ ... }