Директивы, не работающие с FormControl после обновления до Angular 9

Я использовал директивы для включения и отключения форм. Это отдельный файл машинописного текста. Код приведен ниже: -

import { NgControl } from '@angular/forms';
import { Directive, Input } from '@angular/core';

@Directive({
    selector: '[disableControl]'
})
export class DisableControlDirective {
    @Input('disableControl') set disableControl( condition : boolean ) {
        const action = condition ? 'disable' : 'enable';
        this.ngControl.control[action]();
    }
    constructor (private ngControl : NgControl){}
}

HTML: -

<div class="card" *ngIf="commentsFormEnable">
    <div class="card">
      <h3 class="mb-0">
        <button class="btn  btn-primary btn-sm" aria-expanded="false">
          Comments
        </button>
      </h3>
      <form [formGroup]="commentsForm" data-target="comments" id="commentsForm" (ngSubmit)="onSubmit($event)">
        <div class="row">
          <div class="col">
            <div class="input-group mb-3">
              <div class="input-group-prepend">
                <span class="input-group-text">Comments</span>
              </div>
              <textarea formControlName="comment" class="form-control" [disableControl]="comments" placeholder="Add a comment."></textarea>
            </div>
          </div>
        </div>
        <div class="row">
          <div class="col text-right">
            <ng-container *ngIf="comments; else commentsbtnElseBlock">
              <ng-container *ngTemplateOutlet="params;context:{btnId: 'comments', toggleValue: comments}"></ng-container>
            </ng-container>
            <ng-template #commentsbtnElseBlock>
              <ng-container *ngTemplateOutlet="paramsElse;context:{btnId: 'comments', toggleValue: comments}"></ng-container>
            </ng-template>
          </div>
        </div>
        <div class="row">
            <div class="col">
                <div *ngFor="let commentData of commentsList; let i=index">
                  <div class="comment-list">
                    <div class="user-initial border rounded-circle">
                      {{commentData.UpdatedBy | slice:0:1}}
                    </div>
                    <div class="comment-info">
                      <ul>
                        <li class="ml-2 mr-2">
                          <span class="user-name">{{commentData.UpdatedBy}}</span>
                        </li>
                        <li>
                          <span>
                            <small>commented {{commentData.UpdatedDate | date:'medium'}}</small>
                          </span>
                       <!--   <i input type="checkbox" class="fas fa-trash-alt" id="{{commentData.RecordId}}" (change)=onChange($event) (click)="deleteCommentsEntity(i,project.ProjectId)"></i>-->
                        </li>
                      </ul>
                    </div>
                    <div class="ml-5 mb-5">
                      {{commentData.Comment}}
                      <!--<div class="project-desc" style="text-align:left; width:3080px">
                        <app-inline-edit [(ngModel)]=commentData.Comment label=commentData.Comment [required]="true" type="input" style="width:300px">
                        </app-inline-edit>
                      </div>-->
                      <button class="btn btn-pill btn-primary btn-sm mr-2" style="text-align:right;color:Tomato;margin-right:20px;float:right" type="button">
                        <i ng-mouseover="count = count + 1" ng-init="count=0" ng-show="Delete" id="{{commentData.RecordId}}" class="fas fa-trash-alt" style="text-align:right;" (click)="deleteCommentsEntity(commentData.RecordId,project.ProjectId)"></i>
                      </button>
                    </div>
                   </div>
                </div>
              </div>
        </div>
      </form>
    </div>
</div>

Меня беспокоит то, что приведенный выше код работает со следующими пакетами: -

"@angular/animations": "^8.0.2",
"@angular/common": "^8.0.2",
"@angular/compiler": "^8.0.2",
"@angular/core": "^8.0.2",
"@angular/forms": "^8.0.2",
"@angular/http": "^8.0.0-beta.10",
"@angular/platform-browser": "^8.0.2",
"@angular/platform-browser-dynamic": "^8.0.2",
"@angular/platform-server": "^8.2.11",
"@angular/router": "^8.0.2",

И не работает с: -

"@angular/animations": "^9.0.0-rc.12",
"@angular/common": "^9.0.0-rc.12",
"@angular/compiler": "^9.0.0-rc.12",
"@angular/core": "^9.0.0-rc.12",
"@angular/forms": "^9.0.0-rc.12",
"@angular/platform-browser": "^9.0.0-rc.12",
"@angular/platform-browser-dynamic": "^9.0.0-rc.12",
"@angular/platform-server": "^8.2.11",
"@angular/router": "^9.0.0-rc.12",

Я получаю эту ошибку -

не может прочитать свойство disabled of undefined в DisableControlDirective. set не может прочитать свойство disable of undefined

Может быть проблема с обновлением версии? Я невежественен. Подскажите, есть ли способ решить эту проблему.


person TechGuru    schedule 05.02.2020    source источник
comment
А можно вместо комментариев поставить истину или ложь? [disableControl] = комментарии. Вы уверены, что комментарии не являются неопределенными?   -  person Fmerco    schedule 05.02.2020
comment
@TechGuru Я не вижу проблемы с текущей версией angular ^9.0.0-rc.12, пожалуйста, проверьте это ng-run-demo < / а>. Не могли бы вы воспроизвести там проблему?   -  person Pankaj Parkar    schedule 05.02.2020
comment
@PankajParkar Вы забыли включить ivy ng-run.com/edit/HOG3ZrXmnwCzBvGExFqb, нам нужно включите его по умолчанию, когда вы находитесь на Angular 9   -  person yurzui    schedule 05.02.2020
comment
@yurzui моя ошибка, кто-нибудь регистрировал эту проблему на github? Мне это кажется критичным.   -  person Pankaj Parkar    schedule 05.02.2020
comment
@PankajParkar Нет, ты можешь :) Но я думаю, они скажут, что работает как задумано   -  person yurzui    schedule 05.02.2020
comment
@yurzui хорошо, я думаю, что это изменение повредит, когда произойдет миграция, часто мы склонны использовать setter вместо ngOnChanges хука   -  person Pankaj Parkar    schedule 05.02.2020


Ответы (1)


По какой-то причине введенный ngControl angular 9 не работает, поскольку он работал в angular 8. В качестве обходного пути вы можете обернуть this.ngControl.controlaction внутри setTimeout

Попробуйте это:

import { NgControl } from '@angular/forms';
import { Directive, Input } from '@angular/core';

@Directive({
    selector: '[disableControl]'
})
export class DisableControlDirective {
        @Input('appDisable') set disableControl( condition : boolean ) {
            const action = condition ? 'disable' : 'enable';
            setTimeout(()=>{
              this.ngControl.control[action]();
            });
       }
    constructor (private ngControl : NgControl){}
}

Или

Вы можете решить эту проблему, прослушивая изменение привязки внутри ngOnChanges следующим образом

 @Input('appDisable') disableControl;
   ngOnChanges(changes) {
    if (changes['disableControl']) {
      const action = this.opDisabled ? 'disable' : 'enable';
      this.ngControl.control[action]();
    }
  }

Для получения дополнительной информации проверьте это

person Chellappan வ    schedule 05.02.2020
comment
Ах. звучит как кодовый запах. setTimeout внутри сеттера :( - person Pankaj Parkar; 05.02.2020
comment
Он отлично работал в angular 8. Как вы думаете, это ошибка в angular 9? @Pankaj Parker? - person Chellappan வ; 05.02.2020
comment
Проверьте мой комментарий здесь, похоже, он отлично работает и с angular 9.rc12. - person Pankaj Parkar; 05.02.2020
comment
@pankaj parker Я пробовал в angular 9 RC-7. Бот работал - person Chellappan வ; 05.02.2020
comment
Подробную информацию можно найти в этой ветке твиттера: twitter.com/yurzui/status/1225050458097704960, Спасибо @yurzui за подробное объяснение. - person Chellappan வ; 05.02.2020