mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
#967 initial support for dynamic components (wip)
- form rendering service to control field-component type mappings - special <form-field> component with dynamic content creation based on mapped types - migrated <text> component to dynamic creation
This commit is contained in:
parent
c9e3723613
commit
4c95ed1f71
@ -19,12 +19,14 @@ import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { CoreModule } from 'ng2-alfresco-core';
|
||||
|
||||
import { ActivitiForm } from './src/components/activiti-form.component';
|
||||
import { FormFieldComponent } from './src/components/form-field/form-field.component';
|
||||
import { ActivitiStartForm } from './src/components/activiti-start-form.component';
|
||||
import { FormService } from './src/services/form.service';
|
||||
import { EcmModelService } from './src/services/ecm-model.service';
|
||||
import { NodeService } from './src/services/node.service';
|
||||
import { WidgetVisibilityService } from './src/services/widget-visibility.service';
|
||||
import { ActivitiAlfrescoContentService } from './src/services/activiti-alfresco.service';
|
||||
import { FormRenderingService } from './src/services/form-rendering.service';
|
||||
import { HttpModule } from '@angular/http';
|
||||
import { WIDGET_DIRECTIVES } from './src/components/widgets/index';
|
||||
|
||||
@ -38,6 +40,7 @@ export * from './src/services/node.service';
|
||||
export const ACTIVITI_FORM_DIRECTIVES: any[] = [
|
||||
ActivitiForm,
|
||||
ActivitiStartForm,
|
||||
FormFieldComponent,
|
||||
...WIDGET_DIRECTIVES
|
||||
];
|
||||
|
||||
@ -46,7 +49,8 @@ export const ACTIVITI_FORM_PROVIDERS: any[] = [
|
||||
EcmModelService,
|
||||
NodeService,
|
||||
WidgetVisibilityService,
|
||||
ActivitiAlfrescoContentService
|
||||
ActivitiAlfrescoContentService,
|
||||
FormRenderingService
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
@ -57,6 +61,9 @@ export const ACTIVITI_FORM_PROVIDERS: any[] = [
|
||||
declarations: [
|
||||
...ACTIVITI_FORM_DIRECTIVES
|
||||
],
|
||||
entryComponents: [
|
||||
...WIDGET_DIRECTIVES
|
||||
],
|
||||
providers: [
|
||||
...ACTIVITI_FORM_PROVIDERS
|
||||
],
|
||||
|
@ -20,6 +20,7 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
import { ActivitiStartForm } from './activiti-start-form.component';
|
||||
import { FormFieldComponent } from './form-field/form-field.component';
|
||||
import { WIDGET_DIRECTIVES } from './widgets/index';
|
||||
import { FormService } from './../services/form.service';
|
||||
import { EcmModelService } from './../services/ecm-model.service';
|
||||
@ -43,6 +44,7 @@ describe('ActivitiStartForm', () => {
|
||||
imports: [ CoreModule ],
|
||||
declarations: [
|
||||
ActivitiStartForm,
|
||||
FormFieldComponent,
|
||||
...WIDGET_DIRECTIVES
|
||||
],
|
||||
providers: [
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, OnInit, ViewChild, ViewContainerRef, Input, ComponentRef, ComponentFactoryResolver, Output, EventEmitter/*, Injector*/ } from '@angular/core';
|
||||
import { WidgetVisibilityService } from './../../services/widget-visibility.service';
|
||||
import { FormRenderingService } from './../../services/form-rendering.service';
|
||||
import { WidgetComponent } from './../widgets/widget.component';
|
||||
import { FormFieldModel/*, FormWidgetModel*/ } from './../widgets/core/index';
|
||||
|
||||
@Component({
|
||||
selector: 'form-field',
|
||||
template: `<div #container></div>`
|
||||
})
|
||||
export class FormFieldComponent implements OnInit {
|
||||
|
||||
@ViewChild('container', { read: ViewContainerRef })
|
||||
container: ViewContainerRef;
|
||||
|
||||
@Input()
|
||||
field: FormFieldModel = null;
|
||||
|
||||
/** @deprecated component handles visibilty itself */
|
||||
@Output()
|
||||
fieldChanged: EventEmitter<FormFieldModel> = new EventEmitter<FormFieldModel>();
|
||||
|
||||
private componentRef: ComponentRef<{}>;
|
||||
|
||||
constructor(
|
||||
private formRenderingService: FormRenderingService,
|
||||
private componentFactoryResolver: ComponentFactoryResolver,
|
||||
private visibilityService: WidgetVisibilityService
|
||||
/*,private injector: Injector*/) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.field) {
|
||||
let componentType = this.formRenderingService.getComponentType(this.field.type);
|
||||
if (componentType) {
|
||||
let factory = this.componentFactoryResolver.resolveComponentFactory(componentType);
|
||||
this.componentRef = this.container.createComponent(factory/*, 0, this.injector*/);
|
||||
let instance = <WidgetComponent>this.componentRef.instance;
|
||||
instance.field = this.field;
|
||||
instance.fieldChanged.subscribe(args => {
|
||||
if (this.field && this.field.form) {
|
||||
this.visibilityService.refreshVisibility(this.field.form);
|
||||
}
|
||||
/** @deprecated */
|
||||
this.fieldChanged.emit(args);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -20,7 +20,7 @@
|
||||
<number-widget [field]="field" (fieldChanged)="fieldChanged($event);"></number-widget>
|
||||
</div>
|
||||
<div *ngSwitchCase="'text'">
|
||||
<text-widget [field]="field" (fieldChanged)="fieldChanged($event);"></text-widget>
|
||||
<form-field [field]="field"></form-field>
|
||||
</div>
|
||||
<div *ngSwitchCase="'multi-line-text'">
|
||||
<multiline-text-widget [field]="field" (fieldChanged)="fieldChanged($event);"></multiline-text-widget>
|
||||
|
@ -23,6 +23,7 @@ import { FormFieldModel } from './../core/form-field.model';
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { CoreModule } from 'ng2-alfresco-core';
|
||||
import { WIDGET_DIRECTIVES } from '../index';
|
||||
import { FormFieldComponent } from './../../form-field/form-field.component';
|
||||
import { fakeFormJson } from '../../../services/assets/widget-visibility.service.mock';
|
||||
|
||||
describe('ContainerWidget', () => {
|
||||
@ -122,7 +123,7 @@ describe('ContainerWidget', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreModule],
|
||||
declarations: [WIDGET_DIRECTIVES]
|
||||
declarations: [FormFieldComponent, WIDGET_DIRECTIVES]
|
||||
}).compileComponents().then(() => {
|
||||
fixture = TestBed.createComponent(ContainerWidget);
|
||||
containerWidgetComponent = fixture.componentInstance;
|
||||
|
@ -22,6 +22,7 @@ import { fakeFormJson } from '../../../services/assets/widget-visibility.service
|
||||
import { TabsWidget } from './tabs.widget';
|
||||
import { TabModel } from '../core/tab.model';
|
||||
import { WIDGET_DIRECTIVES } from '../index';
|
||||
import { FormFieldComponent } from './../../form-field/form-field.component';
|
||||
import { CoreModule } from 'ng2-alfresco-core';
|
||||
|
||||
describe('TabsWidget', () => {
|
||||
@ -102,7 +103,7 @@ describe('TabsWidget', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreModule],
|
||||
declarations: [WIDGET_DIRECTIVES]
|
||||
declarations: [FormFieldComponent, WIDGET_DIRECTIVES]
|
||||
}).compileComponents().then(() => {
|
||||
fixture = TestBed.createComponent(TabsWidget);
|
||||
tabWidgetComponent = fixture.componentInstance;
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable, Type } from '@angular/core';
|
||||
|
||||
import { TextWidget } from './../components/widgets/text/text.widget';
|
||||
|
||||
@Injectable()
|
||||
export class FormRenderingService {
|
||||
|
||||
private types: { [key: string]: Type<{}> } = {
|
||||
'text': TextWidget
|
||||
};
|
||||
|
||||
getComponentType(fieldType: string): Type<{}> {
|
||||
if (fieldType) {
|
||||
return this.types[fieldType] || null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
setComponentType(fieldType: string, componentType: Type<{}>, override: boolean = false) {
|
||||
if (!fieldType) {
|
||||
throw new Error(`fieldType is null or not defined`);
|
||||
}
|
||||
|
||||
if (!componentType) {
|
||||
throw new Error(`componentType is null or not defined`);
|
||||
}
|
||||
|
||||
let existing = this.types[fieldType];
|
||||
if (existing && !override) {
|
||||
throw new Error(`componentType is already mapped, use override option if you intend replacing existing mapping.`);
|
||||
}
|
||||
|
||||
this.types[fieldType] = componentType;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.setComponentType('xx', TextWidget);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user