升级到 Angular 9 后指令无法与 FormControl 一起使用
Directives not working with FormControl after upgrading to 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",
我收到这个错误 -
cannot read property 'disabled' of undefined at
DisableControlDirective.set cannot read property 'disable' of
undefined
会不会是版本升级的问题?我一无所知。请问有什么方法可以解决这个问题。
出于某种原因 angular 9 注入的 ngControl 无法正常工作,因为它在 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]();
}
}
我使用指令来启用和禁用表单。这是一个单独的打字稿文件。代码如下:-
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",
我收到这个错误 -
cannot read property 'disabled' of undefined at DisableControlDirective.set cannot read property 'disable' of undefined
会不会是版本升级的问题?我一无所知。请问有什么方法可以解决这个问题。
出于某种原因 angular 9 注入的 ngControl 无法正常工作,因为它在 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]();
}
}