NativeScript / angular

NativeScript for Angular
https://docs.nativescript.org/tutorials/build-a-master-detail-app-with-angular
43 stars 13 forks source link

Using Standalone Components #142

Open joeskeen opened 3 weeks ago

joeskeen commented 3 weeks ago

Is your feature request related to a problem? Please describe.

According to the Issues list, it should theoretically be possible to create a NativeScript Angular application that contains standalone components; however, I have yet to figure out how to do that without crashing the application. If you look at the application that is generated using `ng new` today, everything is standalone, from the `main.ts` down. It seems that currently `@nativescript/angular` only supports bootstrapping a module, as opposed to an application/component. If I want my main app component to be a standalone component, I can import it into the `AppModule`: ```ts @NgModule({ imports: [NativeScriptModule, AppRoutingModule, AppComponent], bootstrap: [AppComponent], ``` but then it creates the compile error `AppComponent class is a standalone component, which can not be used in the @NgModule.bootstrap array. Use the bootstrapApplication function for bootstrap instead.` When I remove the `bootstrap` option: ``` The module AppModule was bootstrapped, but it does not declare '@NgModule.bootstrap' components nor a "ngDoBootstrap" method. Please define one of these. ``` This happens even if I provide an `ngDoBootstrap()` function: ```ts export class AppModule { ngDoBootstrap() { console.log('ngDoBootstrap'); } } ``` OK, so Angular wants an App Module when bootstrapped to have a non-standalone component to bootstrap. Let's try that: ```ts @Component({ selector: 'ns-root', template: ``, }) export class RootComponent {} @NgModule({ imports: [NativeScriptModule, AppRoutingModule], declarations: [RootComponent], bootstrap: [RootComponent], schemas: [NO_ERRORS_SCHEMA], }) export class AppModule {} ``` This works, but as soon as you try to drop in your standalone component: ```ts @Component({ selector: 'ns-root', template: ``, }) export class RootComponent {} @NgModule({ imports: [NativeScriptModule, AppRoutingModule, AppComponent], declarations: [RootComponent], bootstrap: [RootComponent], schemas: [NO_ERRORS_SCHEMA], }) export class AppModule {} ``` You get a nasty error (at least on my Android Emulator): ``` System.err: An uncaught Exception occurred on "main" thread. System.err: Unable to start activity ComponentInfo{org.nativescript.tracker/com.tns.NativeScriptActivity}: com.tns.NativeScriptException: Calling js method onCreate failed System.err: Error: java.lang.IllegalArgumentException: Cannot add a null child view to a ViewGroup System.err: System.err: StackTrace: System.err: setActivityContent(file: src/webpack:/tracker/node_modules/@nativescript/core/ui/frame/callbacks/activity-callbacks.js:234:0) System.err: at onCreate(file: src/webpack:/tracker/node_modules/@nativescript/core/ui/frame/callbacks/activity-callbacks.js:46:0) System.err: at onCreate(file: src/webpack:/tracker/node_modules/@nativescript/core/ui/frame/activity.android.js:24:0) System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4048) System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4235) System.err: at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:112) System.err: at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:174) System.err: at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:109) System.err: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:81) System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2636) System.err: at android.os.Handler.dispatchMessage(Handler.java:107) System.err: at android.os.Looper.loopOnce(Looper.java:232) System.err: at android.os.Looper.loop(Looper.java:317) System.err: at android.app.ActivityThread.main(ActivityThread.java:8705) System.err: at java.lang.reflect.Method.invoke(Native Method) System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580) System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886) System.err: Caused by: com.tns.NativeScriptException: Calling js method onCreate failed System.err: Error: java.lang.IllegalArgumentException: Cannot add a null child view to a ViewGroup System.err: at com.tns.Runtime.callJSMethodNative(Native Method) System.err: at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1302) System.err: at com.tns.Runtime.callJSMethodImpl(Runtime.java:1188) System.err: at com.tns.Runtime.callJSMethod(Runtime.java:1175) System.err: at com.tns.Runtime.callJSMethod(Runtime.java:1153) System.err: at com.tns.Runtime.callJSMethod(Runtime.java:1149) System.err: at com.tns.NativeScriptActivity.onCreate(NativeScriptActivity.java:57) System.err: at android.app.Activity.performCreate(Activity.java:9002) System.err: at android.app.Activity.performCreate(Activity.java:8980) System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1526) System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4030) System.err: ... 13 more System.err: Caused by: java.lang.IllegalArgumentException: Cannot add a null child view to a ViewGroup System.err: at android.view.ViewGroup.addView(ViewGroup.java:5077) System.err: at android.view.ViewGroup.addView(ViewGroup.java:5057) System.err: at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:719) System.err: at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:207) System.err: ... 24 more ``` **Describe the solution you'd like** A clear and concise example of how to develop a NativeScript Angular app, using standalone components.
akhil02hero commented 2 weeks ago

@joeskeen

@Component({ selector: 'ns-root', template: <GridLayout><Label text="Hello from Root Component"></Label><ns-app></ns-app></GridLayout>, standalone: true, imports: [CommonModule, AppComponent] }) export class RootComponent {}

can you try importing the App Component into the Root Component

joeskeen commented 1 week ago

@akhil02hero but if you make the RootComponent standalone, you get the error I referenced earlier:

RootComponent class is a standalone component, which can not be used in the @NgModule.bootstrap array. Use the bootstrapApplication function for bootstrap instead.

The whole reason I made a RootComponent to hold the AppComponent was so RootComponent could be non-standalone (and thus work).