-
-
Notifications
You must be signed in to change notification settings - Fork 240
Description
Is your feature request related to a problem? Please describe.
Currently angular components cannot be styled through XML attributes nor do they have a representation in the UI tree (e.g. <my-component backgroundColor="red" paddingTop="10">). To overcome this and other limitations, Angular components are frequently wrapped either outside or inside in some kind view container (StackLayout is perhaps the most common).
Describe the solution you'd like
A custom component annotation (either as a replacement or complementary to Angular's @Component) i.e. @NativeScriptComponent which allows the developer to provide a viewClass property to specify which Nativescript view to use for a given component.
Describe alternatives you've considered
Alternatively to the component annotation, one can use registerElement('my-component-selector', () => StackLayout) to manually associate the Angular component with a UI view.
Additional context
PoC for the custom component annotation and use-case:
function NativeScriptComponent(meta: Component & { viewClass: ViewClass }) {
const viewClass = meta.viewClass;
delete meta.viewClass;
const componentMeta = meta as Component;
const ngComponentDecorator = Component(componentMeta);
return function<T extends { new(...args:any[]): {} }>(constructor: T) {
ngComponentDecorator(constructor);
if (!isKnownView(componentMeta.selector)) {
registerElement(componentMeta.selector, () => viewClass);
} else {
console.warn(`Component with selector ${componentMeta.selector} is already registered`);
}
}
}
Component declaration:
@NativeScriptComponent({
moduleId: module.id,
viewClass: StackLayout,
selector: 'nativescript-component',
template: '<Label text="Hello, World"></Label>',
host: {
'class': 'm-10 p-10'
},
})
export class TestComponent implements OnInit {
constructor(private elementRef: ElementRef) {
// elementRef.nativeElement is a StackLayout
}
}
Usage:
<!-- app.component.html -->
<nativescript-component backgroundColor="red"></nativescript-component>
Additional Notes
- This way of overriding the
@Componentannotation might not be supported across all versions of Angular. This was tested with Angular 6. Host propertiesIt does.@Component({ host: { 'borderColor': 'red' }, ... })do not seem to work.registerElementis global while the component is scoped to the module where it is declared and, when exported, the modules that import the declaring module. This means that two components with the same name declared on different modules would clash in theregisterElementphase.