Plunker的一个例子: https://plnkr.co/edit/aWUE54EUMIm8rnw3PZOO?p=preview
第一个按钮递增值。如果该值小于10,则应启用该按钮,否则应禁用该按钮。 第二个按钮将值重置为0.
this.button1 = new ButtonAction(
"info",
"check",
"right",
"Click me!",
"medium",
true,
true,
new Command(
() => this.val += 1,
() => {
return this.val < 10;
}
),
false
);
this.button2 = new ButtonAction(
"info",
"check",
"right",
"Reset first button!",
"medium",
true,
true,
new Command(
() => this.val = 0,
null
),
false
);
当值达到10时,第一个按钮确实会自行禁用,但是当我将值重置为0时,即使输出中的所有内容都正常,它也不会更新:
Marked for check with value 7
btnClass: btn btn-outline-info btn-block
isDisabled: false
Marked for check with value 8
btnClass: btn btn-outline-info btn-block
isDisabled: false
Marked for check with value 9
btnClass: btn btn-outline-info btn-block
isDisabled: false
Marked for check with value 10
btnClass: btn btn-outline-info btn-block disabled
isDisabled: true
Marked for check with value 0
btnClass: btn btn-outline-info btn-block
isDisabled: false
这是设置值的方式:
set val(v: number){
this._val = v;
console.log("Marked for check with value "+this._val);
//this.cd.markForCheck();
this.cd.detectChanges();
}
markForCheck也不起作用所以我真的不知道该做什么,除了通过ElementRef自己处理DOM(已经尝试过它并且它有效),但我真的不想这样做=)
我一直在尝试检测问题,我想生成的工厂类将buttonClasses的先前值与当前值进行比较,当它从btn btn-outline-info btn-block
转到btn btn-outline-info btn-block disabled
时它会起作用,但不是相反的方式周围。
图片显示了当我使用第二个按钮重置值并且buttonClasses在第一次调用之后第一次调用时会发生什么。
self._expr_2是之前的值,它是btn btn-outline-info btn-block
但它也应该有disabled
。当前值没有disabled
类,这是正确的。
提前感谢您的帮助。我真的不知道该怎么做......
答案 0 :(得分:2)
使用ChangeDetectionStrategy.OnPush
策略,您必须调用cd.markForCheck
API方法。
最重要的是:
它标记了从我们的组件到root的路径,以便检查 下次更改检测运行。
因此,您需要在UIButton
ChangeDetectorRefs
点击它,否则更改检测仅在您执行操作后的一个按钮上有效。
每当angular2更改检测时,它会在更改后将视图标记为已检查。
以下是angular2处理点击事件的方式:
<强> UIButton.ngfactory.js 强>
_View_UIButton0.prototype._handle_click_1_0 = function($event) {
var self = this;
self.markPathToRootAsCheckOnce();
self.debug(1,3,14);
var pd_0 = (self.context.clicked() !== false);
return (true && pd_0);
};
注意:
self.markPathToRootAsCheckOnce();
它标记当前要检查的按钮,但第二个按钮将保持ChangeDetectorStatus.Checked
状态,并在检查时省略。
所以你的解决方案可能如下所示:
1)UIButton组件
constructor(public cd: ChangeDetectorRef) {}
2)应用程序组件
@ViewChildren(UIButton) buttons: QueryList<UIButton>;
set val(v: number){
this._val = v;
console.log("Marked for check!");
this.buttons.toArray().forEach(btn => btn.cd.markForCheck());
}
这样两个按钮都会被检查
在行动中查看 Plunker
希望这能帮到你!