di-controls
Version:
<!-- PROJECT LOGO -->
140 lines (139 loc) • 5.39 kB
TypeScript
import { DICompareHost } from 'di-controls/classes';
import { DICompareFunction } from 'di-controls/types';
import { DIControl, DIControlConfig } from './control';
import * as i0 from "@angular/core";
/**
* Configuration for the `DICollectionControl`.
*/
export interface DICollectionControlConfig<TModel, TChildModel> extends DIControlConfig<TModel[], TChildModel> {
/**
* Function that will be used to compare values in the array.
* Useful when you want to compare objects by some property.
*/
compare?: DICompareHost<TModel | null> | DICompareFunction<TModel | null> | null;
}
/**
* `DICollectionControl` can be used to implement array controls (checkbox group, radio group, chips, etc.).
* It has an additional integration with `DIStateControl` that allows you to use it as a host for
* `DIStateControl` controls. If you use `DIStateControl` as a child control, then `DICollectionControl`
* will update its model when the child control is checked or unchecked, so `DICollectionControl` will
* contain only checked values.
*
* It also works with other controls, but their model should be an array.
*
* > **Warning**
* > If child control model is updated with non-array value, then `DICollectionControl` will be updated with `null`.
*
* ## Creating a control
* To create a control you need to extend your `@Component` or `@Directive` from `DICollectionControl` class.
* After that your control will be able to work with `NgModel`, `FormControl`.
*
* ```ts fileName="custom-control.component.ts"
* @Component({})
* export class CustomControlComponent extends DICollectionControl<string> {
* constructor() {
* super();
* }
* }
* ```
*
* ## Registering as a host
* By default your control can work only with `NgModel` and `FormControl`. But you can register your control as a host
* for another controls, then your control will be able to update them and accept updates from them. To do that you need to
* use `provideHostControl` function.
*
* ```ts {2} fileName="custom-control.component.ts"
* @Component({
* providers: [provideHostControl(CustomControlComponent)],
* })
* export class CustomControlComponent extends DICollectionControl<string> {
* constructor() {
* super();
* }
* }
* ```
*
* ## Injecting host control
* By default your control doesn't communicate with host controls. But you can inject host control and put it
* into `super` call. This will register your control in the host control and start communication between them.
*
* > **Note**
* > If you register your control as a host for another controls, then you can inject it
* > only with `skipSelf` option.
*
* ```ts {5} fileName="custom-control.component.ts"
* @Component({})
* export class CustomControlComponent extends DICollectionControl<string> {
* constructor() {
* // we add `optional` option to make it possible to use this control without host
* super({host: injectHostControl({optional: true})});
* }
* }
* ```
*
* ## Getting model
* To get model you need to use `model` property. It will return model for the current control.
*
* ```ts {9} fileName="custom-control.component.ts"
* @Component({})
* export class CustomControlComponent extends DICollectionControl<string> {
* constructor() {
* super();
* }
*
* @HostListener('click')
* onClick() {
* console.log(this.model());
* }
* }
* ```
*
* ## Updating model
* To update model you need to call `updateModel` method. It will update model for the current control and all
* children controls, as well as for the `NgModel` or `FormControl`.
*
* ```ts {9} fileName="custom-control.component.ts"
* @Component({})
* export class CustomControlComponent extends DICollectionControl<string> {
* constructor() {
* super();
* }
*
* @HostListener('click')
* onClick() {
* this.updateModel(['new value']);
* }
* }
* ```
* ## Catching updates
* Sometimes you may need to catch updates from different sources. For example, to update the value of the native
* input element. To do this, you can provide the `onIncomingUpdate` hook.
*
* ```ts {6} fileName="custom-control.component.ts"
* @Component({})
* export class CustomControlComponent extends DICollectionControl<string> {
* constructor() {
* super({
* onIncomingUpdate: (value: string[] | null) => {
* this.elementRef.nativeElement.value = value;
* },
* });
* }
* }
* ```
* ```
*/
export declare abstract class DICollectionControl<TModel> extends DIControl<TModel[], TModel | TModel[]> {
protected config?: DICollectionControlConfig<TModel, TModel | TModel[]> | undefined;
private proxyModel;
protected constructor(config?: DICollectionControlConfig<TModel, TModel | TModel[]> | undefined);
private getCompareFn;
internalUpdateModel(obj: TModel[] | null): void;
writeValue(value: TModel[] | null): void;
writeValueFromHost(obj: TModel[] | null): void;
protected childControlChange(control: DIControl<TModel | TModel[]>, value: TModel[] | null): void;
private getNewModel;
protected updateControl(control: DIControl<TModel | TModel[]>): void;
static ɵfac: i0.ɵɵFactoryDeclaration<DICollectionControl<any>, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<DICollectionControl<any>, never, never, {}, {}, never, never, true, never>;
}