Мой первый компонент
export class EditIntegrationComponentAttributeComponent implements OnInit {
constructor(
private _router: ActivatedRoute,
private _intApi: IntegrationsApiService,
private _spinner: SpinnerService,
private _fb: FormBuilder,
private _routerNavigation: Router,
private _notification: NotificationsService,
) {
this.componentAttributeID = this._router.snapshot.params.id;
}
ngOnInit(): void {
this._spinner.showSpinner('loading');
if (this.isNew) {
this.sources = {
componentAttributes: this._intApi.getIntComponentAttributesOptions(),
componentAttributeType: this._intApi.getIntComponentTypes(),
allComponentAttribute: this._intApi.getIntComponentAttributes()
};
} else {
this.sources = {
componentAttributes: this._intApi.getIntComponentAttributesOptions(),
componentAttribute: this._intApi.getIntComponentAttributeById(this.componentAttributeID),
componentAttributeType: this._intApi.getIntComponentTypes(),
allComponentAttribute: this._intApi.getIntComponentAttributes()
};
}
forkJoin(this.sources).pipe(
finalize(() => {
this._spinner.hideSpinner();
this.isLoading = false;
})
).subscribe(
obj => {
Object.keys(obj).forEach(key => {
this[key] = obj[key];
});
},
(er) => {
// If one call fails then the entire forkjoin fails
// Display a message telling the user there was a problem pulling data
console.log(er);
this.hasLoadingError = true;
},
() => {
this._buildForm(this.componentAttributes);
this._createSectionNames(this.allComponentAttribute);
this.filteredOptions = this.iFg.controls.section_name.valueChanges.pipe(
startWith(''),
map(val => val.length >= 2 ? this._filter(val) : [])
);
}
);
}
/**
* generating form using the controls created by
* fn _createControls
*/
private _buildForm(data) {
this.iFg = this._fb.group(this._createControls(data));
console.log(this.iFg)
}
/**
* * Creating form controls by using the option provided by API
* @params data
*/
private _createControls(data) {
const ctrls = {};
for (const attr in data) {
let str = {};
if ( data[attr].type === 'boolean' ) {
str = {
[attr]: [{
value: this.isNew ? false : this.componentAttribute[attr], disabled: this.isNew ? false : data[attr].read_only
}]
};
} else if ( data[attr].type === 'list' || attr === 'validation_expression' || data[attr].type === 'choice') {
str = {
[attr]: [{
value: this.isNew ? null : this.componentAttribute[attr], disabled: this.isNew ? false : data[attr].read_only
}]
};
} else if ( data[attr].type === 'datetime') {
str = {
[attr]: [{
value: this.isNew ? null : this._formatDate( this.componentAttribute[attr]), disabled: this.isNew ? false : data[attr].read_only
}]
};
} else {
str = {
[attr]: [{
value: this.isNew ? '' : this.componentAttribute[attr], disabled: this.isNew ? false : data[attr].read_only
}]
};
}
Object.assign(ctrls, str);
}
this.isLoading = false;
this._spinner.hideSpinner();
return ctrls;
}
/**
* * getter method for checking if component is new or old
*/
get isNew() {
return !this.componentAttributeID;
}
/**
* * Save the updated/New Component Attribute
*/
public saveAttribute() {
// remove null and empty from data
this._spinner.showSpinner('saving');
const obj = this.iFg.value;
Object.keys(obj).forEach(k => (!obj[k] && obj[k] !== false) && delete obj[k]);
if (!this.isNew) {
if (this.isTypeChanged) { this.iFg.value.ordering = 1; }
this._intApi.updateIntComponentAttribute(this.componentAttributeID, obj).subscribe(
(data) => {
console.log(data);
this._spinner.hideSpinner();
this._notification.success('', 'Component Attribute Updated');
},
(err) => {
console.log(err);
this._spinner.hideSpinner();
this._notification.error('', 'Component Attribute can not be updated please check logs');
}
);
} else {
this._intApi.postIntComponentAttribute(this.iFg.value).subscribe(
(data) => {
console.log(data);
this._notification.success('', 'Component Attribute Added');
this._spinner.hideSpinner();
this._routerNavigation.navigateByUrl('/admin/integration/component-attributes/edit/' + data.id);
},
(err) => {
console.log(err);
this._spinner.hideSpinner();
this._notification.error('', 'Component Attribute can not be updated please check console');
}
);
}
}
/**
* * adding choice in the choices array
*/
public removeChoicesFromList(value): void {
const index = this.componentAttribute.choices.indexOf(value);
if (index >= 0) {
this.componentAttribute.choices.splice(index, 1);
}
}
/**
* * removing choice from the choices array
*/
public addChoicesToList(event: MatChipInputEvent): void {
console.log(this.iFg.value);
if (this.iFg.value.choices === null || this.iFg.value.choices === '') {
this.iFg.value.choices = [];
}
const input = event.input;
const value = event.value;
if ((value || '').trim()) {
this.iFg.value.choices.push(value.trim());
}
// Reset the input value
if (input) {
input.value="";
}
}
public deleteComponentAttribute() {
if (confirm('Are you sure you want to delete Component Attribute')) {
this._intApi.removeIntComponentAttribute(this.componentAttributeID).subscribe(
(data) => {
this._notification.success('', 'Component Attribute deleted successfully');
this._routerNavigation.navigateByUrl('/admin/integration/component-attributes');
},
() => {
this._notification.warn('', 'Can not delete Component Attribute');
}
);
}
}
public onCancel() {
this._routerNavigation.navigateByUrl('/admin/integration/component-attributes');
}
private _formatDate(params: any): string {
return new Date(params).toLocaleDateString();
}
private _filter(value: string): string[] {
const filterValue = value.toLowerCase();
return this.options.filter(option => option.toLowerCase().indexOf(filterValue) === 0);
}
private _createSectionNames(obj) {
const key = this.componentAttribute.component_type;
this.options = [... new Set (obj.filter(attribute => attribute.component_type === key).map(attr => attr.section_name).filter( ob => ob != null))];
}
}
Мой второй компонент
@Component({
selector: 'app-edit-note-type',
templateUrl: './edit-note-type.component.html',
styleUrls: ['./edit-note-type.component.scss']
})
export class EditNoteTypeComponent implements OnInit {
private noteTypeID;
public sources: object;
public isLoading = false;
public hasLoadingError = false;
public noteTypeOptions: IntUrlType[] = [];
public noteTypeDetails: IntUrlType;
public noteTypeFg: FormGroup;
public chk ;
constructor(
private _router: ActivatedRoute,
private _intApi: IntegrationsApiService,
private _spinner: SpinnerService,
private _fb: FormBuilder,
private _routerNavigation: Router,
private _notification: NotificationsService,
private _auth: AuthorizationService,
private _adminApi: AdminApiService
) {
this.noteTypeID = this._router.snapshot.params.id; // for navigation to new server page
}
ngOnInit(): void {
this.isLoading = true;
this._spinner.showSpinner('loading');
if (this.isNew) {
this.sources = {
noteTypeOptions: this._intApi.getIntNoteCategoriesOptions(),
};
} else {
this.sources = {
noteTypeOptions: this._intApi.getIntNoteCategoriesOptions(),
noteTypeDetails: this._intApi.getIntNoteCategoriesById(this.noteTypeID),
};
}
forkJoin(this.sources).pipe(
finalize(() => {
this._spinner.hideSpinner();
this.isLoading = false;
})
).subscribe(
obj => {
Object.keys(obj).forEach(key => {
this[key] = obj[key];
});
this.chk = [this.noteTypeOptions];
},
(er) => {
// If one call fails then the entire forkjoin fails
// Display a message telling the user there was a problem pulling data
console.log(er);
this.hasLoadingError = true;
},
() => {this._buildForm(this.noteTypeOptions); }
);
}
/**
* * getter method for checking if component is new or old
*/
get isNew() {
return !this.noteTypeID;
}
/**
* generating form using the controls created by
* fn _createControls
*/
private _buildForm(data) {
this.noteTypeFg = this._fb.group(this._createControls(data));
}
/**
* * Creating form controls by using the option provided by API
* @params data
*/
private _createControls(data) {
const ctrls: object = {};
for (const attr in data) {
let str = {};
if ( data[attr].type === 'boolean' ) {
str = {
[attr]: [{
value: this.isNew ? true : this.noteTypeDetails[attr], disabled: this.isNew ? false : data[attr].read_only
}]
};
} else if ( data[attr].type === 'list' || attr === 'validation_expression' || data[attr].type === 'choice') {
str = {
[attr]: [{
value: this.isNew ? null : this.noteTypeDetails[attr], disabled: this.isNew ? false : data[attr].read_only
}]
};
} else if ( data[attr].type === 'datetime') {
str = {
[attr]: [{
value: this.isNew ? null : this._formatDate( this.noteTypeDetails[attr]), disabled: this.isNew ? false : data[attr].read_only
}]
};
} else {
str = {
[attr]: [{
value: this.isNew ? '' : this.noteTypeDetails[attr], disabled: this.isNew ? false : data[attr].read_only
}]
};
}
Object.assign(ctrls, str);
}
this.isLoading = false;
this._spinner.hideSpinner();
return ctrls;
}
public onCancel() {
this._routerNavigation.navigateByUrl('/admin/integration/note-type');
}
private _formatDate(params: any): string {
return new Date(params).toLocaleDateString();
}
/**
* * Save the updated/New Note Type
*/
public saveNoteType() {
this._spinner.showSpinner('saving');
const obj = this.noteTypeFg.value;
Object.keys(obj).forEach(k => (!obj[k] && obj[k] !== false) && delete obj[k]);
if (!this.isNew) {
this._intApi.updateIntNoteCategory(this.noteTypeID, obj).subscribe(
(data) => {
this._spinner.hideSpinner();
this._routerNavigation.navigateByUrl('/admin/integration/note-type/edit/' + data.id);
this._notification.success('', 'Successfully Saved');
},
(err) => {
console.log(err);
this._spinner.hideSpinner();
this._notification.error('', 'Not Saved! Please check Error in logs');
}
);
} else {
this._intApi.postIntNoteCategory(this.noteTypeFg.value).subscribe(
(data) => {
this._notification.success('', 'Type Added');
this._spinner.hideSpinner();
this._routerNavigation.navigateByUrl('/admin/integration/note-type/edit/' + data.id);
},
(err) => {
console.log(err);
this._spinner.hideSpinner();
this._notification.error('', 'Not Saved');
}
);
}
}
public deleteNoteType() {
if (confirm('Are you sure you want to delete category')) {
this._intApi.removeIntNoteCategory(this.noteTypeID).subscribe(
(data) => {
this._notification.success('', 'Category deleted successfully');
this._routerNavigation.navigateByUrl('/admin/integration/note-type');
},
() => {
this._notification.warn('', 'Can not delete');
}
);
}
}
}
У меня есть еще один компонент, который выполняет ту же операцию Crud, используя тот же API, но с разными методами. Я хочу создать родительский класс, который может уменьшить количество кода, повторяющегося в каждом классе компонентов. Я пробовал, но не уверен, как передать разные методы из дочернего класса в родительский.