Javascript Angular 7[禁用]在嵌套对象';s的属性值被更改
我需要编写一个通用函数,根据JSON中的条件启用/禁用按钮 JSON: 在JSON中,我有两个按钮“PURCHASE_LIEN”和“NOT_QUALIFIED”。这两个函数都有基于条件的条件数组,按钮应使用“disable”属性启用/禁用 VALIDATION.SERVICE.TS 下面的函数将根据对象的条件设置按钮的禁用属性(selectedRow)Javascript Angular 7[禁用]在嵌套对象';s的属性值被更改,javascript,angular,Javascript,Angular,我需要编写一个通用函数,根据JSON中的条件启用/禁用按钮 JSON: 在JSON中,我有两个按钮“PURCHASE_LIEN”和“NOT_QUALIFIED”。这两个函数都有基于条件的条件数组,按钮应使用“disable”属性启用/禁用 VALIDATION.SERVICE.TS 下面的函数将根据对象的条件设置按钮的禁用属性(selectedRow) validation service中的disableButton方法会根据条件将DISABLE属性值更改为true/false,但该按钮不会启
validation service中的disableButton方法会根据条件将DISABLE属性值更改为true/false,但该按钮不会启用。它不检测变化角度变化检测是一个巨大的课题。这里有一个嵌套的对象,angular必须跟踪以检测变化 因此,我们没有选择递归地检查对象的每个字段,并将其与以前的状态进行比较,以检测是否进行了任何更改。此步骤是调用摘要并标记为脏。这是angular在非常特殊的情况下执行此操作的原因(列表不完整仅用于演示):
- @输出是触发器
- @输入是变异的
- 浏览器事件为分派(单击、悬停等)
- 超时
- 间歇
myPreviousObject!==myNewObject
而不是:
if (
myPreviousObject.prop1 !== myNewObject.prop1 ||
myPreviousObject.prop2 !== myPreviousObject.prop2 ||
....
)
- 使用不可变状态的observatable
export interface disableState {
PURCHASE_LIEN: {
disable: boolean;
disable$: BehaviorSubject<boolean>
};
NOT_QUALIFIED: {
disable: boolean;
disable$: BehaviorSubject<boolean>
};
}
全部组成部分:
@组件({
选择器:“我的应用程序”,
templateUrl:“./app.component.html”,
样式URL:['./app.component.css'],
changeDetection:ChangeDetectionStrategy.OnPush
})
导出类AppComponent{
disableState:disableState={
不合格:{
禁用:false,
禁用$:新行为主体(false),
},
购买留置权:{
禁用:false,
禁用$:新行为主体(false),
},
}
showmodel(id:string){
log(`openmodal:${id}`);
}
dummyPropertyChange(){
/**
*致电您的服务,如:
*this.validation.disableButton()
*/
this.disableState['NOT_QUALIFIED'].disable=true;
this.disableState['NOT_QUALIFIED'].disable$.next(true);
}
}
请注意,我已经切换了ChangeDetectionStrategy
,要求angular仅通过简单对象比较(而不是嵌套对象)执行脏检查。从现在起,如果我想更新数据,我应该:
- 更改整个变量数据(而不仅仅是嵌套属性)
- 使用observable在时间线上执行更改
import {
Directive,
Renderer2,
ElementRef,
Input,
OnChanges
} from '@angular/core';
@Directive({
selector: '[appBtnDisable]'
})
export class BtnDisableDirective implements OnChanges {
@Input() buttonContainer: any = {};
@Input() buttonID = '';
@Input() condition: any = {};
constructor(public ele: ElementRef, public renderer: Renderer2) {
if (this.buttonID) {
this.disableButton(this.buttonContainer, this.buttonID, this.condition);
}
}
ngOnChanges() {
if (this.buttonID) {
this.disableButton(this.buttonContainer, this.buttonID, this.condition);
}
}
public disableButton(
buttonContainer: any,
buttonID: string,
selectedRow: any
) {
for (let i = 0; i < buttonContainer[buttonID]['CONDITION'].length; i++) {
const condition = buttonContainer[buttonID]['CONDITION'][i];
let status = true;
for (const conditionName in condition) {
if (
this.convertNulltoUndefined(condition[conditionName]) !== this.evaluate(conditionName, selectedRow)
) {
status = false;
}
}
if (status) {
this.ele.nativeElement.disabled = false;
break;
} else {
this.ele.nativeElement.disabled = true;
}
}
}
evaluate(data: string, selectedRow: any): any {
if (data.split('.').length > 1) {
const value = 'selectedRow.' + data;
try {
return eval(value);
} catch (error) {
return undefined;
}
} else {
return selectedRow[data];
}
}
convertNulltoUndefined(data) {
return (data === null) ? undefined : data;
}
}
导入{
指令,
渲染器2,
ElementRef,
输入,
一旦改变
}从“@angular/core”开始;
@指示({
选择器:“[AppBndisable]”
})
导出类BtnDisableDirective实现OnChanges{
@Input()按钮容器:any={};
@Input()按钮ID='';
@Input()条件:any={};
构造函数(public ele:ElementRef,public renderer:render2){
如果(这个按钮){
this.disableButton(this.buttonContainer,this.buttonID,this.condition);
}
}
ngOnChanges(){
如果(这个按钮){
this.disableButton(this.buttonContainer,this.buttonID,this.condition);
}
}
公共禁用按钮(
按钮容器:任何,
buttonID:字符串,
selectedRow:任何
) {
for(设i=0;i1){
常量值='selectedRow.'+数据;
试一试{
返回eval(value);
}捕获(错误){
返回未定义;
}
}否则{
返回selectedRow[数据];
}
}
convertNulltoUndefined(数据){
返回(数据===null)?未定义:数据;
}
}
app.component.html
<div class="col-12 col-sm-6 col-md-4 col-lg-2">
<button class="btn btn-primary btn-semi-circle" (click)="showModal('Purchase')"
[disabled]="disableButton(buttonGroup, 'PURCHASE_LIEN', selectedRowData)">Purchase
Lien</button>
<!-- [disabled]="PURCHASE_LIEN_DISABLE" -->
</div>
<div class="col-12 col-sm-6 col-md-4 col-lg-2">
<button class="btn btn-danger btn-semi-circle" (click)="showModal('Not Qualified')"
[disabled]="disableButton(buttonGroup, 'NOT_QUALIFIED', selectedRowData)">Not
Qualified</button>
<!-- [disabled]="NOT_QUALIFIED_DISABLE" -->
</div>
<button class="btn btn-primary btn-semi-circle" (click)="showModal('Purchase')"
appBtnDisable [condition]="selectedRowData" [buttonContainer]="buttonGroup" [buttonID]="'PURCHASE_LIEN'">Purchase
Lien</button>
购买
留置权
能否创建堆栈闪电战
?控制台日志在返回按钮容器之前代码>以查看布尔值。我已使用开发人员控制台检查了对象,属性发生了更改,但angular未检测到更改可能的重复项。我没有询问DOM操作。我只想知道angular如何知道对象属性已经更改,以便angular检测到它并更新禁用按钮的属性为什么我们不能在没有out指令的情况下实现这一点
export interface disableState {
PURCHASE_LIEN: {
disable: boolean;
disable$: BehaviorSubject<boolean>
};
NOT_QUALIFIED: {
disable: boolean;
disable$: BehaviorSubject<boolean>
};
}
disableState: disableState = {
NOT_QUALIFIED: {
disable: false,
disable$: new BehaviorSubject<boolean>(false),
},
PURCHASE_LIEN: {
disable: false,
disable$: new BehaviorSubject<boolean>(false),
},
}
/**
* Call your service like :
* this.validation.disableButton()
*/
this.disableState['NOT_QUALIFIED'].disable = true;
this.disableState['NOT_QUALIFIED'].disable$.next(true);
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
disableState: disableState = {
NOT_QUALIFIED: {
disable: false,
disable$: new BehaviorSubject<boolean>(false),
},
PURCHASE_LIEN: {
disable: false,
disable$: new BehaviorSubject<boolean>(false),
},
}
showModal(id: string) {
console.log(`Open modal : ${id}`);
}
dummyPropertyChange() {
/**
* Call your service like :
* this.validation.disableButton()
*/
this.disableState['NOT_QUALIFIED'].disable = true;
this.disableState['NOT_QUALIFIED'].disable$.next(true);
}
}
import {
Directive,
Renderer2,
ElementRef,
Input,
OnChanges
} from '@angular/core';
@Directive({
selector: '[appBtnDisable]'
})
export class BtnDisableDirective implements OnChanges {
@Input() buttonContainer: any = {};
@Input() buttonID = '';
@Input() condition: any = {};
constructor(public ele: ElementRef, public renderer: Renderer2) {
if (this.buttonID) {
this.disableButton(this.buttonContainer, this.buttonID, this.condition);
}
}
ngOnChanges() {
if (this.buttonID) {
this.disableButton(this.buttonContainer, this.buttonID, this.condition);
}
}
public disableButton(
buttonContainer: any,
buttonID: string,
selectedRow: any
) {
for (let i = 0; i < buttonContainer[buttonID]['CONDITION'].length; i++) {
const condition = buttonContainer[buttonID]['CONDITION'][i];
let status = true;
for (const conditionName in condition) {
if (
this.convertNulltoUndefined(condition[conditionName]) !== this.evaluate(conditionName, selectedRow)
) {
status = false;
}
}
if (status) {
this.ele.nativeElement.disabled = false;
break;
} else {
this.ele.nativeElement.disabled = true;
}
}
}
evaluate(data: string, selectedRow: any): any {
if (data.split('.').length > 1) {
const value = 'selectedRow.' + data;
try {
return eval(value);
} catch (error) {
return undefined;
}
} else {
return selectedRow[data];
}
}
convertNulltoUndefined(data) {
return (data === null) ? undefined : data;
}
}
<button class="btn btn-primary btn-semi-circle" (click)="showModal('Purchase')"
appBtnDisable [condition]="selectedRowData" [buttonContainer]="buttonGroup" [buttonID]="'PURCHASE_LIEN'">Purchase
Lien</button>