当我尝试迭代 ngFor 循环时,Angular 2+ attr.disabled 不适用于 div
Angular 2+ attr.disabled is not working for div when I try to iterate ngFor loop
我正在开发一个约会应用程序,我在其中使用 *ngFor
循环显示约会的时间段。
html
<div *ngFor="let item of allTimeSlots">
<div class="col-sm-3">
<div class="choice" data-toggle="wizard-slot" [attr.disabled]="item.status" (click)="slotSelected($event)">
<input type="radio" name="slot" value="{{item.timeSlot}}">
<span class="icon">{{item.timeSlot}}</span> {{item.status}}
</div>
</div>
</div>
打字稿
for (var index = 0; index < this.totalMinutes; index += 15, i++) {
this.allTimeSlots[i] = new allTimeSlots("", false);
this.allTimeSlots[i].timeSlot = (hour <= 12 ? hour : hour - 12) + ":" + (minute <= 9 ? ("0" + minute) : minute) + " " + ampm;
this.bookedTimeSlots.forEach(element => {
if (this.allTimeSlots[i].timeSlot == element) {
this.allTimeSlots[i].status = true;
}
});
}
这是时间段的屏幕截图,如果时间段已预订,则显示 true
,如果可用于调试目的,则显示 false。
当我 运行 此代码时,它不会抛出任何错误,但 *ngFor
创建的所有 div
元素都被禁用。我尝试使用 *ngIf
而不是禁用,效果很好。但是问题是我想显示时间段是否可用
使用[disabled]
代替[attr.disabled]
这是因为 [attr.disabled]="false"
将向 html 中的元素添加 disabled="false"
,但仍会禁用该元素
不会禁用元素的语法
<button>Not Disabled</button>
<button [disabled]="false">Not Disabled</button>
将禁用元素的语法
<button disabled></button>
<button disabled="true"></button>
<button disabled="false"></button>
<button [attr.disabled]="true"></button>
<button [attr.disabled]="false"></button>
<button [disabled]="true"></button>
disabled
将禁用一个元素,无论它是真还是假,它的存在意味着该元素将被禁用。如果 variable
为假,Angular 将不会为 [disabled]="variable"
添加 disabled
元素。
正如您在评论中提到的,您使用的是 div
元素而不是按钮,angular 2 无法识别其中的禁用元素。如果您要捕获 click
事件,我建议您使用按钮,但如果不是,您可以执行以下操作:
<div [ngClass]="{ 'disabled': item.status }"></div>
并有一个 CSS class 来显示已预订的时间段。
有关 [ngClass]
的更多信息,请参阅 the documentation
正如 0mpurdy 所回答的那样,您应该使用 [disabled] 属性。变量不必是布尔值,但表达式应该是。
在您的代码中,它确定 item.status 是假的还是真实的。因此,如果它不是 null/NaN/undefined,您将得到“true”并且 div 将被禁用。
而是插入一个表达式:
[disabled]="item.status === 'occupied'"
编辑
抱歉我错过了。
由于您无法禁用 div,因此请将禁用的属性放入输入标签中。
<input type="radio" [disabled]="item.status === 'occupied'" name="slot" value="{{item.timeSlot}}">
由于您想将选择显示为已禁用,因此需要将其直接放在输入中。单选按钮将不可点击,并且将显示 'cursor: not-allowed'。
希望对您有所帮助
Disabled 不能用于 div 元素,只能应用于以下元素
<button>
<fieldset>
<input>
<keygen>
<optgroup>
<option>
<select>
<textarea>
所以对于你的问题,你可以通过以下方式处理:
<div
class="choice"
data-toggle="wizard-slot"
[class.disabled]="item.status"
(click)="slotSelected($event)">
<input
type="radio"
name="slot"
value="{{item.timeSlot}}"
[disabled]="item.status">
<span class="icon">{{item.timeSlot}}</span> {{item.status}}
</div>
你应该添加样式
.disabled {
cursor: not-allowed;
}
这样使用:
[attr.disabled]="isDisabled ? '' : null"
同样适用于只读。
CSS
.disabled-contenct {
pointer-events: none;
opacity: 0.4;
}
HTML
<div [class.disabled-contenct]="!isDisabledContent"></div>
TS
isDisabledContent: boolean;
然后您可以随时切换 isDisabledContent。
属性指令肯定会帮助您禁用或启用 div 或任何其他 HTML 元素及其子元素。
DisableDirective
首先,创建一个将一个参数 (appDisable) 作为输入的属性指令。它将根据输入 disable/enable DOM 元素及其子 DOM 元素。
import { AfterViewInit, Directive, ElementRef, Input, OnChanges, Renderer2 } from '@angular/core';
const DISABLED = 'disabled';
const APP_DISABLED = 'app-disabled';
const TAB_INDEX = 'tabindex';
const TAG_ANCHOR = 'a';
@Directive({
selector: '[appDisable]'
})
export class DisableDirective implements OnChanges, AfterViewInit {
@Input() appDisable = true;
constructor(private eleRef: ElementRef, private renderer: Renderer2) { }
ngOnChanges() {
this.disableElement(this.eleRef.nativeElement);
}
ngAfterViewInit() {
this.disableElement(this.eleRef.nativeElement);
}
private disableElement(element: any) {
if (this.appDisable) {
if (!element.hasAttribute(DISABLED)) {
this.renderer.setAttribute(element, APP_DISABLED, '');
this.renderer.setAttribute(element, DISABLED, 'true');
// disabling anchor tab keyboard event
if (element.tagName.toLowerCase() === TAG_ANCHOR) {
this.renderer.setAttribute(element, TAB_INDEX, '-1');
}
}
} else {
if (element.hasAttribute(APP_DISABLED)) {
if (element.getAttribute('disabled') !== '') {
element.removeAttribute(DISABLED);
}
element.removeAttribute(APP_DISABLED);
if (element.tagName.toLowerCase() === TAG_ANCHOR) {
element.removeAttribute(TAB_INDEX);
}
}
}
if (element.children) {
for (let ele of element.children) {
this.disableElement(ele);
}
}
}
}
Do not forget to register DisableDirective in the AppModule
如何在组件中使用指令?
在组件的指令中传递布尔值 (true/false)。
<div class="container" [appDisable]="true">
</div>
你可以参考完整的PostHERE
运行 Stackblitz
示例
有一种方法可以使用 attribute binding. It is a simple method. See the docs 如何实施。
我正在开发一个约会应用程序,我在其中使用 *ngFor
循环显示约会的时间段。
html
<div *ngFor="let item of allTimeSlots">
<div class="col-sm-3">
<div class="choice" data-toggle="wizard-slot" [attr.disabled]="item.status" (click)="slotSelected($event)">
<input type="radio" name="slot" value="{{item.timeSlot}}">
<span class="icon">{{item.timeSlot}}</span> {{item.status}}
</div>
</div>
</div>
打字稿
for (var index = 0; index < this.totalMinutes; index += 15, i++) {
this.allTimeSlots[i] = new allTimeSlots("", false);
this.allTimeSlots[i].timeSlot = (hour <= 12 ? hour : hour - 12) + ":" + (minute <= 9 ? ("0" + minute) : minute) + " " + ampm;
this.bookedTimeSlots.forEach(element => {
if (this.allTimeSlots[i].timeSlot == element) {
this.allTimeSlots[i].status = true;
}
});
}
这是时间段的屏幕截图,如果时间段已预订,则显示 true
,如果可用于调试目的,则显示 false。
当我 运行 此代码时,它不会抛出任何错误,但 *ngFor
创建的所有 div
元素都被禁用。我尝试使用 *ngIf
而不是禁用,效果很好。但是问题是我想显示时间段是否可用
使用[disabled]
代替[attr.disabled]
这是因为 [attr.disabled]="false"
将向 html 中的元素添加 disabled="false"
,但仍会禁用该元素
不会禁用元素的语法
<button>Not Disabled</button>
<button [disabled]="false">Not Disabled</button>
将禁用元素的语法
<button disabled></button>
<button disabled="true"></button>
<button disabled="false"></button>
<button [attr.disabled]="true"></button>
<button [attr.disabled]="false"></button>
<button [disabled]="true"></button>
disabled
将禁用一个元素,无论它是真还是假,它的存在意味着该元素将被禁用。如果 variable
为假,Angular 将不会为 [disabled]="variable"
添加 disabled
元素。
正如您在评论中提到的,您使用的是 div
元素而不是按钮,angular 2 无法识别其中的禁用元素。如果您要捕获 click
事件,我建议您使用按钮,但如果不是,您可以执行以下操作:
<div [ngClass]="{ 'disabled': item.status }"></div>
并有一个 CSS class 来显示已预订的时间段。
有关 [ngClass]
的更多信息,请参阅 the documentation
正如 0mpurdy 所回答的那样,您应该使用 [disabled] 属性。变量不必是布尔值,但表达式应该是。
在您的代码中,它确定 item.status 是假的还是真实的。因此,如果它不是 null/NaN/undefined,您将得到“true”并且 div 将被禁用。
而是插入一个表达式:
[disabled]="item.status === 'occupied'"
编辑
抱歉我错过了。 由于您无法禁用 div,因此请将禁用的属性放入输入标签中。
<input type="radio" [disabled]="item.status === 'occupied'" name="slot" value="{{item.timeSlot}}">
由于您想将选择显示为已禁用,因此需要将其直接放在输入中。单选按钮将不可点击,并且将显示 'cursor: not-allowed'。
希望对您有所帮助
Disabled 不能用于 div 元素,只能应用于以下元素
<button>
<fieldset>
<input>
<keygen>
<optgroup>
<option>
<select>
<textarea>
所以对于你的问题,你可以通过以下方式处理:
<div
class="choice"
data-toggle="wizard-slot"
[class.disabled]="item.status"
(click)="slotSelected($event)">
<input
type="radio"
name="slot"
value="{{item.timeSlot}}"
[disabled]="item.status">
<span class="icon">{{item.timeSlot}}</span> {{item.status}}
</div>
你应该添加样式
.disabled {
cursor: not-allowed;
}
这样使用:
[attr.disabled]="isDisabled ? '' : null"
同样适用于只读。
CSS
.disabled-contenct {
pointer-events: none;
opacity: 0.4;
}
HTML
<div [class.disabled-contenct]="!isDisabledContent"></div>
TS
isDisabledContent: boolean;
然后您可以随时切换 isDisabledContent。
属性指令肯定会帮助您禁用或启用 div 或任何其他 HTML 元素及其子元素。
DisableDirective
首先,创建一个将一个参数 (appDisable) 作为输入的属性指令。它将根据输入 disable/enable DOM 元素及其子 DOM 元素。
import { AfterViewInit, Directive, ElementRef, Input, OnChanges, Renderer2 } from '@angular/core';
const DISABLED = 'disabled';
const APP_DISABLED = 'app-disabled';
const TAB_INDEX = 'tabindex';
const TAG_ANCHOR = 'a';
@Directive({
selector: '[appDisable]'
})
export class DisableDirective implements OnChanges, AfterViewInit {
@Input() appDisable = true;
constructor(private eleRef: ElementRef, private renderer: Renderer2) { }
ngOnChanges() {
this.disableElement(this.eleRef.nativeElement);
}
ngAfterViewInit() {
this.disableElement(this.eleRef.nativeElement);
}
private disableElement(element: any) {
if (this.appDisable) {
if (!element.hasAttribute(DISABLED)) {
this.renderer.setAttribute(element, APP_DISABLED, '');
this.renderer.setAttribute(element, DISABLED, 'true');
// disabling anchor tab keyboard event
if (element.tagName.toLowerCase() === TAG_ANCHOR) {
this.renderer.setAttribute(element, TAB_INDEX, '-1');
}
}
} else {
if (element.hasAttribute(APP_DISABLED)) {
if (element.getAttribute('disabled') !== '') {
element.removeAttribute(DISABLED);
}
element.removeAttribute(APP_DISABLED);
if (element.tagName.toLowerCase() === TAG_ANCHOR) {
element.removeAttribute(TAB_INDEX);
}
}
}
if (element.children) {
for (let ele of element.children) {
this.disableElement(ele);
}
}
}
}
Do not forget to register DisableDirective in the AppModule
如何在组件中使用指令?
在组件的指令中传递布尔值 (true/false)。
<div class="container" [appDisable]="true">
</div>
你可以参考完整的PostHERE
运行 Stackblitz
示例有一种方法可以使用 attribute binding. It is a simple method. See the docs 如何实施。