Доступ к ControlValueAccessor из другого компонента - PullRequest
0 голосов
/ 28 октября 2018

У меня есть компонент, в котором я реализую ControlValueAccessor, и у меня возникают проблемы с пониманием правильного способа его использования:

import { Component, OnInit, forwardRef, Output, EventEmitter, OnChanges, Input, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { UserOrEmail } from '../entities/UserOrEmail';

export const USER_INPUT_CONTROL_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    // tslint:disable-next-line
    useExisting: forwardRef(() => AddUserOrEmailComponent),
    multi: true,
};

const noop = () => {
    // Placeholder operation
};
@Component({
    selector: 'app-add-user-or-email',
    templateUrl: './add-user-or-email.component.html',
    providers: [USER_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class AddUserOrEmailComponent implements OnInit, ControlValueAccessor {
    @Input()
    user: any = UserOrEmail;

    @Output()
    change: EventEmitter<UserOrEmail> = new EventEmitter<UserOrEmail>();

    users: any = [];
    ngOnInit() {
        this.user = {
            userId: 'ull',
            name: 'null',
            email: 'null'
        };
        this.users = ConstantService.UserArray;
    }

    // #region [ Value Accessor Interface ]--------------------------------------------------------

    // Placeholders for the callbacks which are later provided
    // by the Control Value Accessor
    private onTouchedCallback: () => void = noop;
    private onChangeCallback: (_: any) => void = noop;

    get value(): any {
        return this.user;
    }

    // [ ControlValueAccessor interface implementation ]-------------------------------------------
    set value(v: any) {
        if (this.user !== v) {
            this.user = <UserOrEmail>v;
            this.onChangeCallback(v);
            this.change.next(this.user);
        }
    }

    writeValue(value: any) {
        if (value !== this.user)
            this.user = <UserOrEmail>value;
    }

    registerOnChange(fn: any) {
        this.onChangeCallback = fn;
    }

    registerOnTouched(fn: any) {
        this.onTouchedCallback = fn;
    }
}

и html:

<div>
    <div class="form-column">
        <div class="form-row">
            <label>
                {{'GENERIC.USER'|translate}}
            </label>
            <select>
                <option [ngValue]="'default'"></option>
                <option *ngFor="let user of users" [ngValue]="user">{{user.login}}</option>
            </select>
        </div>
        <div class="form-row">
            <label for="addPersonEmail" >{{'GENERIC.EMAIL' | translate}}</label>
            <input type="email"  placeholder="{{'GENERIC.EMAIL'|translate}}" pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$">
        </div>
    </div>
</div>

Я пытаюсь использовать его в другом компоненте:

hmtl:

<app-modal class="form" #addMilestoneModal [width]="550">
    <div header>{{'MODALS.ADD_MILESTONE'|translate}}</div>
    <div body>
        <div class="form-column">
            <div class="form-value">
                <app-add-user-or-email #addUser [(ngModel)]="milestone.assignee"></app-add-user-or-email>
            </div>
            <div class="form-row">
                <label for="addMilestoneDescription">{{'GENERIC.DESCRIPTION' | translate}}</label>
                <textarea style="height: 150px" [(ngModel)]="milestone.description"></textarea>
            </div>

        </div>
    </div>
    <div footer class="flex-container">
        <button class="flex-item-row btn btn-a" [disabled]="!milestone.description" (click)="apply()">{{'GENERIC.APPLY'
            | translate}}</button>
    </div>
</app-modal>

Машинопись:

import { Component, ViewChild, EventEmitter } from '@angular/core';
import { ModalComponent } from '../../widgets/modal/modal.component';
import { Milestone } from '../../entities/Milestone';
import { ConstantService } from '../../services/ConstantService';
import { AddUserOrEmailComponent } from '../../add-user-or-email/add-user-or-email.component';

@Component({
  selector: 'app-add-milestone-modal',
  templateUrl: './add-milestone-modal.component.html'
})
export class AddMilestoneModalComponent {

  @ViewChild('addMilestoneModal')
  modal: ModalComponent;

  cs = ConstantService;

  emitter: EventEmitter<Milestone> = new EventEmitter<Milestone>();

  milestone: any = Milestone;
  apply() {
    console.log(this.milestone); // <---- HERE IT SHOULD BE ACCESSED
    debugger;
    this.emitter.next(this.milestone);
    this.modal.close();
  }

  cancel() {
    this.emitter.next(null);
    this.modal.close();
  }
}

Я должен получить его в milestone объекте, но он пуст.Чего мне не хватает?

1 Ответ

0 голосов
/ 28 октября 2018

У меня были проблемы с этим пару недель назад, и я создал StackBlitz с хорошим примером.

Надеюсь, это поможет вам?

https://stackblitz.com/edit/mat-select-with-controlvalueaccessor

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...