Hva er beste praksis for å lage en AngularJS 1.5-komponent i Typescript?
Jeg eksperimenterer med .component()-syntaksen i Angular 1.5.
Det ser ut til at den nyeste moten er å kode controlleren direkte i komponenten i stedet for i en egen fil, og jeg kan se fordelen med det gitt at komponentens standardoppsett er minimalt.
Problemet er at jeg har kodet kontrollerne mine som TypeScript-klasser og ønsker å fortsette å gjøre det fordi det ser ut til å være i samsvar med Angular2.
Min beste innsats er noe sånt som dette:
export let myComponent = {
template: ($element, $attrs) => {
return [
`<my-html>Bla</my-html>`
].join('')
},
controller: MyController
};
class MyController {
}
Det fungerer, men det er ikke elegant. Finnes det en bedre måte?
Svar #1
Hvis du ønsket å fullstendig adoptere en Angular 2-tilnærming, kunne du bruke:
module.ts
import { MyComponent } from './MyComponent';
angular.module('myModule', [])
.component('myComponent', MyComponent);
MinKomponent.ts
import { Component } from './decorators';
@Component({
bindings: {
prop: '<'
},
template: '<p>{{$ctrl.prop}}</p>'
})
export class MyComponent {
prop: string;
constructor(private $q: ng.IQService) {}
$onInit() {
// do something with this.prop or this.$q upon initialization
}
}
decorators.ts
/// <reference path="../typings/angularjs/angular.d.ts" />
export const Component = (options: ng.IComponentOptions) => {
return controller => angular.extend(options, { controller });
};
Svar #2
Jeg bruker en enkel Typescript-dekoratør for å lage komponenten
function Component(moduleOrName: string | ng.IModule, selector: string, options: {
controllerAs?: string,
template?: string,
templateUrl?: string
}) {
return (controller: Function) => {
var module = typeof moduleOrName === "string"
? angular.module(moduleOrName)
: moduleOrName;
module.component(selector, angular.extend(options, { controller: controller }));
}
}
så jeg kan bruke det slik
@Component(app, 'testComponent', {
controllerAs: 'ct',
template: `
<pre>{{ct}}</pre>
<div>
<input type="text" ng-model="ct.count">
<button type="button" ng-click="ct.decrement();">-</button>
<button type="button" ng-click="ct.increment();">+</button>
</div>
`
})
class CounterTest {
count = 0;
increment() {
this.count++;
}
decrement() {
this.count--;
}
}
Du kan prøve en fungerende jsbin her http://jsbin.com/jipacoxeki/edit?html,js,output
Svar #3
Dette er mønsteret jeg bruker:
ZippyKomponent.ts
import {ZippyController} from './ZippyController';
export class ZippyComponent implements ng.IComponentOptions {
public bindings: {
bungle: '<',
george: '<'
};
public transclude: boolean = false;
public controller: Function = ZippyController;
public controllerAs: string = 'vm';
public template: string = require('./Zippy.html');
}
ZippyController.ts
export class ZippyController {
bungle: string;
george: Array<number>;
static $inject = ['$timeout'];
constructor (private $timeout: ng.ITimeoutService) {
}
}
Zippy.html
<div class="zippy">
{{vm.bungle}}
<span ng-repeat="item in vm.george">{{item}}</span>
</div>
main.ts
import {ZippyComponent} from './components/Zippy/ZippyComponent';
angular.module('my.app', [])
.component('myZippy', new ZippyComponent());
