Sometimes it is great to have possibility to create custom form elements in angular 4.
Let's not waste time and look at how it is done by example for the case when we want to access values from "contenteditable" div.

Firstly we will create a custom value accessor directive for our contenteditable div
import {
    Directive,
    ElementRef,
    Renderer,
    forwardRef
} from '@angular/core';
import {
    ControlValueAccessor,
    NG_VALUE_ACCESSOR
} from '@angular/forms';

const DIV_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => DivValueAccessor),
    multi: true
};

@Directive({
    selector: 'div[formControlName]',
    host: {
        '(input)': 'onChange($event.target)',
        '(blur)' : 'onTouched()'
    },
    providers: [DIV_VALUE_ACCESSOR]
})
export class DivValueAccessor implements ControlValueAccessor {
    onChange = (_) => {};
    onTouched = () => {};

    constructor(
        private _renderer: Renderer,
        private _elementRef: ElementRef
    ) {}

    public writeValue(value: any): void {
        var normalizedValue = (value == null || value === '') ?
                '' :
                value.replace(/^s|s$/g, ' ');
        this._renderer.setElementProperty(this._elementRef.nativeElement,
            'innerHTML', normalizedValue);
    }

    public registerOnChange(fn: (_: any) => void): void {
        this.onChange = (target: any) => {
            fn(target.innerText);
        };
    }

    public registerOnTouched(fn: () => void): void {
        this.onTouched = fn;
    }
}
And now let's see how we can apply our value accessor to "div" with editable content:
<div contenteditable="true" ngDefaultControl formControlName="postText"></div>
Please note that it is important to set ngDefaultControl attribute to apply the value accessor.