diff --git a/README.md b/README.md
index 1405aa7..05f435e 100644
--- a/README.md
+++ b/README.md
@@ -106,23 +106,48 @@ export function dropDownSelectedIndexChanged(args: SelectedIndexChangedEventData
}
```
-## Angular 2 Example
+## Angular
+##### Migration to 3.0+
+
+- Remove:
+```typescript
+registerElement("DropDown", () => require("nativescript-drop-down/drop-down").DropDown);`
+```
+- Import `DropDownModule` in `NgModule`:
+```typescript
+import { DropDownModule } from “nativescript-drop-down/angular”;
+…
+@NgModule({
+ …
+ imports: [
+ …
+ DropDownModule,
+ …
+ ],
+ …
+})
+```
+
+##### Example Usage
```TypeScript
// main.ts
-import { platformNativeScriptDynamic, NativeScriptModule } from "nativescript-angular/platform";
import { NgModule } from "@angular/core";
+import { NativeScriptModule } from "nativescript-angular/nativescript.module";
+import { platformNativeScriptDynamic } from "nativescript-angular/platform";
+import { DropDownModule } from "nativescript-drop-down/angular";
import { AppComponent } from "./app.component";
-import { registerElement } from "nativescript-angular/element-registry";
-
-registerElement("DropDown", () => require("nativescript-drop-down/drop-down").DropDown);
@NgModule({
- declarations: [AppComponent],
- bootstrap: [AppComponent],
- imports: [NativeScriptModule],
+ declarations: [ AppComponent ],
+ bootstrap: [ AppComponent ],
+ imports: [
+ NativeScriptModule,
+ DropDownModule,
+ ],
})
-class AppComponentModule {}
+class AppComponentModule {
+}
platformNativeScriptDynamic().bootstrapModule(AppComponentModule);
```
@@ -130,13 +155,24 @@ platformNativeScriptDynamic().bootstrapModule(AppComponentModule);
```HTML
-
-
-
-
-
+
+
+
+
```
diff --git a/angular/index.ts b/angular/index.ts
new file mode 100644
index 0000000..ad0c070
--- /dev/null
+++ b/angular/index.ts
@@ -0,0 +1,78 @@
+import { AfterViewInit, Directive, ElementRef, HostListener, Inject, NgModule, forwardRef } from "@angular/core";
+import { FormsModule, NG_VALUE_ACCESSOR } from "@angular/forms";
+import { BaseValueAccessor, registerElement } from "nativescript-angular";
+import { convertToInt } from "nativescript-angular/common/utils";
+import { View } from "tns-core-modules/ui/core/view";
+
+registerElement("DropDown", () => require("../drop-down").DropDown);
+
+const SELECTED_INDEX_VALUE_ACCESSOR = {provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => SelectedIndexValueAccessor), multi: true};
+
+export type SelectableView = {selectedIndex: number} & View;
+
+/**
+ * The accessor for setting a selectedIndex and listening to changes that is used by the
+ * {@link NgModel} directives.
+ *
+ * ### Example
+ * ```
+ *
+ * ```
+ */
+@Directive({
+ // tslint:disable-next-line:max-line-length directive-selector
+ selector: "DropDown[ngModel], DropDown[formControlName], dropDown[ngModel], dropDown[formControlName], drop-down[ngModel], drop-down[formControlName]",
+ providers: [SELECTED_INDEX_VALUE_ACCESSOR]
+})
+export class SelectedIndexValueAccessor extends BaseValueAccessor implements AfterViewInit { // tslint:disable-line:max-line-length directive-class-suffix
+
+ private _normalizedValue: number;
+ private viewInitialized: boolean;
+
+ constructor(@Inject(ElementRef) elementRef: ElementRef) {
+ super(elementRef.nativeElement);
+ }
+
+ @HostListener("selectedIndexChange", ["$event"])
+ public selectedIndexChangeListener(event: any) {
+ this.onChange(event.value);
+ }
+
+ // tslint:disable-next-line:no-empty
+ public onTouched = () => { };
+
+ public writeValue(value: any): void {
+ if (value === undefined || value === null || value === "") {
+ this._normalizedValue = null;
+ }
+ else {
+ this._normalizedValue = convertToInt(value);
+ }
+
+ if (this.viewInitialized) {
+ this.view.selectedIndex = this._normalizedValue;
+ }
+ }
+
+ public ngAfterViewInit() {
+ this.viewInitialized = true;
+ this.view.selectedIndex = this._normalizedValue;
+ }
+
+ public registerOnTouched(fn: () => void): void { this.onTouched = fn; }
+}
+
+@NgModule({
+ declarations: [ SelectedIndexValueAccessor ],
+ providers: [],
+ imports: [
+ FormsModule
+ ],
+ exports: [
+ FormsModule,
+ SelectedIndexValueAccessor
+ ]
+})
+export class DropDownModule {
+}
diff --git a/demo-ng/app/app.module.ts b/demo-ng/app/app.module.ts
index 565ad54..f43976a 100644
--- a/demo-ng/app/app.module.ts
+++ b/demo-ng/app/app.module.ts
@@ -4,6 +4,7 @@ import { AppRoutingModule } from "./app.routing";
import { AppComponent } from "./app.component";
import { DropDownComponent } from "./dropdown/dropdown.component";
+import { DropDownModule } from 'nativescript-drop-down/angular';
@NgModule({
bootstrap: [
@@ -11,6 +12,7 @@ import { DropDownComponent } from "./dropdown/dropdown.component";
],
imports: [
NativeScriptModule,
+ DropDownModule,
AppRoutingModule
],
declarations: [
diff --git a/demo-ng/app/dropdown/dropdown.component.html b/demo-ng/app/dropdown/dropdown.component.html
index 35489d7..3c395c7 100644
--- a/demo-ng/app/dropdown/dropdown.component.html
+++ b/demo-ng/app/dropdown/dropdown.component.html
@@ -1,13 +1,29 @@
-
-
+
-
-
-
-
-
-
+
+
+
+
+
diff --git a/demo-ng/app/dropdown/dropdown.component.ts b/demo-ng/app/dropdown/dropdown.component.ts
index 16520c5..bb6bb57 100644
--- a/demo-ng/app/dropdown/dropdown.component.ts
+++ b/demo-ng/app/dropdown/dropdown.component.ts
@@ -8,27 +8,30 @@ import { SelectedIndexChangedEventData, ValueList } from "nativescript-drop-down
})
export class DropDownComponent implements OnInit {
public selectedIndex: number = null;
- public hint = "My Hint";
+ public hint = "My Hint";
public items: ValueList;
- public cssClass: string = "default";
+ public cssClass: string = "default";
public ngOnInit() {
this.items = new ValueList();
- for (let loop = 0; loop < 200; loop++) {
- this.items.push({ value: `I${loop}`, display: `Item ${loop}`});
+ for ( let loop = 0; loop < 200; loop++ ) {
+ this.items.push({
+ value: `I${loop}`,
+ display: `Item ${loop}`,
+ });
}
}
public onchange(args: SelectedIndexChangedEventData) {
- console.log(`Drop Down selected index changed from ${args.oldIndex} to ${args.newIndex}. New value is '${this.items.getValue(args.newIndex)}'`);
- this.selectedIndex = args.newIndex;
+ console.log(`Drop Down selected index changed from ${args.oldIndex} to ${args.newIndex}. New value is "${this.items.getValue(
+ args.newIndex)}"`);
}
public onopen() {
console.log("Drop Down opened.");
}
-
+
public changeStyles() {
this.cssClass = "changed-styles";
- }
+ }
}
diff --git a/demo-ng/app/main.ts b/demo-ng/app/main.ts
index 22f21ea..1057aef 100644
--- a/demo-ng/app/main.ts
+++ b/demo-ng/app/main.ts
@@ -1,10 +1,6 @@
// this import should be first in order to load some required settings (like globals and reflect-metadata)
import { platformNativeScriptDynamic } from "nativescript-angular/platform";
-import { registerElement } from "nativescript-angular/element-registry";
-
import { AppModule } from "./app.module";
-registerElement("DropDown", () => require("nativescript-drop-down/drop-down").DropDown);
-
platformNativeScriptDynamic().bootstrapModule(AppModule);
diff --git a/demo-ng/package.json b/demo-ng/package.json
index b1fab86..63cc3c1 100644
--- a/demo-ng/package.json
+++ b/demo-ng/package.json
@@ -15,15 +15,15 @@
"debug-ios": "npm uninstall nativescript-drop-down && tns debug ios --emulator"
},
"dependencies": {
- "@angular/animations": "4.0.0",
- "@angular/common": "4.0.0",
- "@angular/compiler": "4.0.0",
- "@angular/core": "4.0.0",
- "@angular/forms": "4.0.0",
- "@angular/http": "4.0.0",
- "@angular/platform-browser": "4.0.0",
- "@angular/platform-browser-dynamic": "4.0.0",
- "@angular/router": "4.0.0",
+ "@angular/animations": "^4.0.3",
+ "@angular/common": "^4.0.3",
+ "@angular/compiler": "^4.0.3",
+ "@angular/core": "^4.0.3",
+ "@angular/forms": "^4.0.3",
+ "@angular/http": "^4.0.3",
+ "@angular/platform-browser": "^4.0.3",
+ "@angular/platform-browser-dynamic": "^4.0.3",
+ "@angular/router": "^4.0.3",
"nativescript-angular": "rc",
"nativescript-drop-down": "file:../bin/dist",
"reflect-metadata": "~0.1.8",
diff --git a/drop-down.android.ts b/drop-down.android.ts
index 3045df2..7bccc7e 100644
--- a/drop-down.android.ts
+++ b/drop-down.android.ts
@@ -73,12 +73,6 @@ export class DropDown extends DropDownBase {
spinner.setOnTouchListener(touchListener);
(spinner as any).touchListener = touchListener;
- // When used in templates the selectedIndex changed event is fired before the native widget is init.
- // So here we must set the inital value (if any)
- if (!types.isNullOrUndefined(this.selectedIndex)) {
- this.android.setSelection(this.selectedIndex + 1); // +1 for the hint first element
- }
-
return spinner;
}
@@ -89,6 +83,12 @@ export class DropDown extends DropDownBase {
nativeView.adapter.owner = new WeakRef(this);
nativeView.itemSelectedListener.owner = new WeakRef(this);
nativeView.touchListener.owner = new WeakRef(this);
+
+ // When used in templates the selectedIndex changed event is fired before the native widget is init.
+ // So here we must set the inital value (if any)
+ if (!types.isNullOrUndefined(this.selectedIndex)) {
+ this.android.setSelection(this.selectedIndex + 1); // +1 for the hint first element
+ }
}
public disposeNativeView() {
diff --git a/gruntfile.js b/gruntfile.js
index f058a2b..f626cee 100644
--- a/gruntfile.js
+++ b/gruntfile.js
@@ -47,6 +47,9 @@
tsCompile: {
cmd: "node ./node_modules/typescript/bin/tsc --project tsconfig.json --outDir " + localConfig.outDir
},
+ ngCompile: {
+ cmd: "node ./node_modules/.bin/ngc --project tsconfig.aot.json --outDir " + localConfig.outDir
+ },
tslint: {
cmd: "node ./node_modules/tslint/bin/tslint --project tsconfig.json"
},
@@ -65,6 +68,7 @@
"exec:tslint",
"clean:build",
"exec:tsCompile",
+ "exec:ngCompile",
"copy"
]);
grunt.registerTask("publish", [
diff --git a/package.json b/package.json
index 86bbc75..e8d2aa0 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,10 @@
},
"devDependencies": {
+ "@angular/compiler-cli": "^4.0.3",
+ "@angular/core": "^4.0.3",
+ "@angular/forms": "^4.0.3",
+ "nativescript-angular": "rc",
"typescript": "~2.2.2",
"tslint": "^4.5.1",
"tns-core-modules": "rc",
diff --git a/tsconfig.aot.json b/tsconfig.aot.json
new file mode 100644
index 0000000..db6f6c6
--- /dev/null
+++ b/tsconfig.aot.json
@@ -0,0 +1,30 @@
+{
+ "compilerOptions": {
+ "noEmitOnError": true,
+ "noEmitHelpers": true,
+ "sourceMap": false,
+ "removeComments": true,
+ "declaration": true,
+ "experimentalDecorators": true,
+ "target": "es5",
+ "module": "commonjs",
+ "outDir": "bin/dist",
+ "lib": ["es6", "dom", "es2015.iterable"],
+ "rootDir": ".",
+ "baseUrl": ".",
+ "paths": {
+ "*": [
+ "./node_modules/tns-core-modules/*",
+ "./node_modules/*"
+ ]
+ },
+ "emitDecoratorMetadata": true,
+ "moduleResolution": "node"
+ },
+ "files": [
+ "angular/index.ts"
+ ],
+ "angularCompilerOptions": {
+ "skipTemplateCodegen": true
+ }
+}
\ No newline at end of file