Skip to content

Commit

Permalink
Make Angular component consumable multiple times
Browse files Browse the repository at this point in the history
The JSONForms Angular component needs the jsonforms service
to set the right data, schema, uischema etc.
The problem is, that the service is a singleton,
as it is registering as a root service.

This commit introduces a new root component `jsonforms`
which allows to pass all parameters into the component.
The component is now initializing the service internally.
Furthermore, the service is not registered as a root service anymore.
Now multiple jsonforms components can be used next to each other.

The angular tests were adapted to work with the behavior change.
  • Loading branch information
eneufeld committed Nov 25, 2020
1 parent a51e373 commit 80ee94e
Show file tree
Hide file tree
Showing 13 changed files with 347 additions and 171 deletions.
100 changes: 53 additions & 47 deletions packages/angular-material/example/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
The MIT License
Copyright (c) 2017-2019 EclipseSource Munich
Copyright (c) 2017-2020 EclipseSource Munich
https://github.com/eclipsesource/jsonforms
Permission is hereby granted, free of charge, to any person obtaining a copy
Expand All @@ -23,19 +23,34 @@
THE SOFTWARE.
*/
import { Component } from '@angular/core';
import { JsonFormsAngularService } from '@jsonforms/angular';
import { ExampleDescription, getExamples } from '@jsonforms/examples';
import {
Actions,
getData,
getUiSchema,
setLocale,
setReadonly,
UISchemaElement,
UISchemaTester,
unsetReadonly,
setConfig
} from '@jsonforms/core';
import { getExamples } from '@jsonforms/examples';
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
import { angularMaterialRenderers } from '../../src/index';
import { clone } from 'lodash';
const uiSchema = {
type: 'HorizontalLayout',
elements: [
{
type: 'Control',
scope: '#/properties/buyer/properties/email'
},
{
type: 'Control',
scope: '#/properties/status'
}
]
};
const itemTester: UISchemaTester = (_schema, schemaPath, _path) => {
if (schemaPath === '#/properties/warehouseitems/items') {
return 10;
}
return -1;
};
@Component({
selector: 'app-root',
template: `
Expand All @@ -45,7 +60,7 @@ import { map } from 'rxjs/operators';
Example:
<select (change)="onChange($event)">
<option
*ngFor="let example of exampleData$ | async"
*ngFor="let example of examples"
value="{{ example.name }}"
label="{{ example.label }}"
>
Expand All @@ -61,61 +76,52 @@ import { map } from 'rxjs/operators';
{{ readonly ? 'Unset' : 'Set' }} Readonly
</button>
</div>
<jsonforms-outlet></jsonforms-outlet>
<jsonforms
[data]="selectedExample.data"
[schema]="selectedExample.schema"
[uischema]="selectedExample.uischema"
[renderers]="renderers"
(dataChange)="onDataChange($event)"
[locale]="currentLocale"
[uischemas]="uischemas"
></jsonforms>
`
})
export class AppComponent {
readonly exampleData$ = of(getExamples());
readonly renderers = angularMaterialRenderers;
readonly examples = getExamples();
selectedExample: ExampleDescription;
currentLocale = 'en-US';
private readonly = false;
data: any;
uischemas: { tester: UISchemaTester; uischema: UISchemaElement; }[] = [
{ tester: itemTester, uischema: uiSchema }
];

constructor(private jsonformService: JsonFormsAngularService) {
const examples = getExamples();
const selectedExample = examples[0];
this.jsonformService.updateCore(
Actions.init(
selectedExample.data,
selectedExample.schema,
selectedExample.uischema
)
);

this.jsonformService.$state.pipe(
map(state => getData(state))
).subscribe(data => this.data = data);
constructor() {
this.selectedExample = this.examples[19];
}
examples() {
return getExamples();

onDataChange(data: any) {
this.data = data;
}

onChange = (ev: any) => {
const examples = getExamples();
const selectedExample = examples.find(e => e.name === ev.target.value);
this.jsonformService.updateCore(
Actions.init(
selectedExample.data,
selectedExample.schema,
selectedExample.uischema
)
);
this.jsonformService.updateConfig(setConfig(selectedExample.config));
this.jsonformService.updateLocale(setLocale(this.currentLocale));
};
onChange(ev: any) {
this.selectedExample = this.examples.find(e => e.name === ev.target.value);
}

changeLocale(locale: string) {
this.currentLocale = locale;
this.jsonformService.updateLocale(setLocale(locale));
}

setReadonly() {
const uischema = getUiSchema(this.jsonformService.getState());
const newUiSchema = clone(this.selectedExample.uischema);
if (this.readonly) {
unsetReadonly(uischema);
unsetReadonly(newUiSchema);
} else {
setReadonly(uischema);
setReadonly(newUiSchema);
}
this.readonly = !this.readonly;
this.jsonformService.updateCore(Actions.setUISchema(uischema));
this.selectedExample.uischema = newUiSchema;
}
}
42 changes: 1 addition & 41 deletions packages/angular-material/example/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
The MIT License
Copyright (c) 2017-2019 EclipseSource Munich
Copyright (c) 2017-2020 EclipseSource Munich
https://github.com/eclipsesource/jsonforms
Permission is hereby granted, free of charge, to any person obtaining a copy
Expand All @@ -25,13 +25,9 @@
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { Actions, UISchemaTester } from '@jsonforms/core';
import { AppComponent } from './app.component';
import { JsonFormsAngularMaterialModule } from '../../src/module';

import { initialState } from './store';
import { JsonFormsAngularService } from '@jsonforms/angular';

@NgModule({
declarations: [AppComponent],
imports: [
Expand All @@ -43,40 +39,4 @@ import { JsonFormsAngularService } from '@jsonforms/angular';
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule {
constructor(jsonformsService: JsonFormsAngularService) {

jsonformsService.init(initialState.jsonforms);
const example = initialState.examples.data[19];

jsonformsService.updateCore(
Actions.init(example.data, example.schema, example.uischema)
);

const uiSchema = {
type: 'HorizontalLayout',
elements: [
{
type: 'Control',
scope: '#/properties/buyer/properties/email'
},
{
type: 'Control',
scope: '#/properties/status'
}
]
};
const itemTester: UISchemaTester = (_schema, schemaPath, _path) => {
if (schemaPath === '#/properties/warehouseitems/items') {
return 10;
}
return -1;
};
jsonformsService.updateUiSchema(Actions.registerUISchema(itemTester, uiSchema));
}
}

/*
Copyright 2017-2018 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
9 changes: 7 additions & 2 deletions packages/angular-material/test/autocomplete-control.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,14 @@ describe('AutoComplete control Error Tests', () => {
setupMockStore(fixture, {
uischema,
schema,
data,
errors
data
});
const formsService = getJsonFormsService(component);
// tslint:disable-next-line: no-string-literal
formsService['_state'].core.errors = errors;
// tslint:disable-next-line: no-string-literal
formsService['updateSubject']();

component.ngOnInit();
fixture.detectChanges();
const debugErrors: DebugElement[] = fixture.debugElement.queryAll(
Expand Down
24 changes: 14 additions & 10 deletions packages/angular-material/test/date-control.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,17 +251,21 @@ describe('Date control Error Tests', () => {
setupMockStore(fixture, {
uischema,
schema,
data,
errors: [
{
dataPath: 'foo',
message: 'Hi, this is me, test error!',
params: '',
keyword: '',
schemaPath: ''
}
]
data
});
const formsService = getJsonFormsService(component);
// tslint:disable-next-line: no-string-literal
formsService['_state'].core.errors = [
{
dataPath: 'foo',
message: 'Hi, this is me, test error!',
params: '',
keyword: '',
schemaPath: ''
}
];
// tslint:disable-next-line: no-string-literal
formsService['updateSubject']();

component.ngOnInit();
fixture.detectChanges();
Expand Down
24 changes: 14 additions & 10 deletions packages/angular-test/src/boolean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,22 +279,26 @@ export const booleanErrorTest = <C extends JsonFormsControl, I>(
it('should display errors', () => {
component.uischema = uischema;

getJsonFormsService(component).init({
const formsService = getJsonFormsService(component);
formsService.init({
core: {
data,
schema: defaultBooleanTestSchema,
errors: [
{
dataPath: 'foo',
message: 'Hi, this is me, test error!',
keyword: '',
params: '',
schemaPath: ''
}
],
uischema: undefined
}
});
// tslint:disable-next-line: no-string-literal
formsService['_state'].core.errors = [
{
dataPath: 'foo',
message: 'Hi, this is me, test error!',
keyword: '',
schemaPath: '',
params: ''
}
];
// tslint:disable-next-line: no-string-literal
formsService['updateSubject']();

component.ngOnInit();
fixture.detectChanges();
Expand Down
24 changes: 14 additions & 10 deletions packages/angular-test/src/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,22 +339,26 @@ export const numberErrorTest = <C extends JsonFormsControl>(
it('should display errors', () => {
component.uischema = testData.uischema;

getJsonFormsService(component).init({
const formsService = getJsonFormsService(component);
formsService.init({
core: {
data: testData.data,
schema: testData.schema,
errors: [
{
dataPath: 'foo',
message: 'Hi, this is me, test error!',
keyword: '',
schemaPath: '',
params: ''
}
],
uischema: undefined
}
});
// tslint:disable-next-line: no-string-literal
formsService['_state'].core.errors = [
{
dataPath: 'foo',
message: 'Hi, this is me, test error!',
keyword: '',
schemaPath: '',
params: ''
}
];
// tslint:disable-next-line: no-string-literal
formsService['updateSubject']();
component.ngOnInit();
fixture.detectChanges();
const debugErrors: DebugElement[] = fixture.debugElement.queryAll(
Expand Down
25 changes: 15 additions & 10 deletions packages/angular-test/src/range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,22 +323,27 @@ export const rangeErrorTest = <C extends JsonFormsControl, I>(
component.uischema = rangeDefaultTestData.uischema;
component.schema = rangeDefaultTestData.schema;

getJsonFormsService(component).init({
const formsService = getJsonFormsService(component);
formsService.init({
core: {
data: rangeDefaultTestData.data,
schema: rangeDefaultTestData.schema,
errors: [
{
dataPath: 'foo',
message: 'Hi, this is me, test error!',
params: '',
schemaPath: '',
keyword: ''
}
],
uischema: undefined
}
});
// tslint:disable-next-line: no-string-literal
formsService['_state'].core.errors = [
{
dataPath: 'foo',
message: 'Hi, this is me, test error!',
keyword: '',
schemaPath: '',
params: ''
}
];
// tslint:disable-next-line: no-string-literal
formsService['updateSubject']();

component.ngOnInit();
fixture.detectChanges();
const debugErrors: DebugElement[] = fixture.debugElement.queryAll(
Expand Down
Loading

0 comments on commit 80ee94e

Please sign in to comment.