将模型更改注册到 MDL 输入元素
Register model changes to MDL input elements
将 MDL 与框架集成时,框架将直接设置输入值,但 MDL 库不会注意到这些更改,因为它们很可能绑定到单击和更改事件。例如,如果我有:
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="joke" pattern="-?[0-9]*(\.[0-9]+)?">
<label class="mdl-textfield__label" for="joke">Joke...</label>
<span class="mdl-textfield__error">Input is not a number!</span>
</div>
然后用一些 javascript:
更改值
document.getElementById('joke').value=text;
元素标签不动,被文字覆盖。总之,is-dirty
class没有设置
这是一个更详细地说明问题的示例。 https://plnkr.co/6pAh7ApQT8TUUS9G9QBg
我目前正在 Angular2 中从事一个项目,但我认为总体问题与框架无关。我希望有比我的 'answer'.
更好的解决方案
更新的答案:
绑定到 class 列表,https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ngClass,可能是更好的方法:
示例:
<div class="mdl-textfield mdl-js-textfield mdl-text-field--floating-label"
[class.is-dirty]=" val != null && val != '' ">
或者对于 mdl-tabs:
<div class="mdl-tabs__panel"
[class.is-active]="val_is_active_tab">
或者对于 mdl-checkboxes:
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect"
[class.is-checked]="val == 1">
原回答:
对于我的项目,我的临时解决方案是放入一些非常非 angular2 的代码:
private thingsToDirty = [];
ngAfterViewChecked() {
for (let id of this.thingsToDirty) {
let el: any = document.getElementById(id);
if (el != undefined &&
el.parentNode.className.indexOf("is-dirty") == -1) {
el.parentNode.className += " is-dirty";
}
}
this.thingsToDirty.length = 0;
}
ngOnInit() {
this.something.getJSONfromServer().subscribe( data => {
this.thing = data;
this.thingsToDirty.push('thing_id');
});
}
我找到的最佳解决方案是使用指令。您可以在元素上调用 checkDirty()。
import { Directive, AfterViewInit, ElementRef, AfterViewChecked} from '@angular/core';
declare var componentHandler: any;
@Directive({
selector: '[mdl]'
})
export class MDL implements AfterViewInit {
constructor(private element: ElementRef) {
}
ngAfterViewInit() {
componentHandler.upgradeAllRegistered();
}
ngAfterViewChecked() {
let mdlField = this.element.nativeElement.MaterialTextfield;
if (mdlField) {
mdlField.checkDirty();
mdlField.checkValidity();
}
}
}
然后,在您的模板中,只需将此指令包含在 mdl 输入
的父级 div 中
<div mdl class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--5-col mdl-cell--8-col-tablet mdl-cell--4-col-phone">
<label class="mdl-textfield__label" for="promoCode_{{inRibbon}}">Promo code</label>
<input class="mdl-textfield__input" type="text" id="promoCode" name="promoCode_{{inRibbon}}" [ngModelOptions]="{standalone: true}" [(ngModel)]="itemAvailabilityRequest.promoCode">
</div>
将 MDL 与框架集成时,框架将直接设置输入值,但 MDL 库不会注意到这些更改,因为它们很可能绑定到单击和更改事件。例如,如果我有:
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="joke" pattern="-?[0-9]*(\.[0-9]+)?">
<label class="mdl-textfield__label" for="joke">Joke...</label>
<span class="mdl-textfield__error">Input is not a number!</span>
</div>
然后用一些 javascript:
更改值document.getElementById('joke').value=text;
元素标签不动,被文字覆盖。总之,is-dirty
class没有设置
这是一个更详细地说明问题的示例。 https://plnkr.co/6pAh7ApQT8TUUS9G9QBg
我目前正在 Angular2 中从事一个项目,但我认为总体问题与框架无关。我希望有比我的 'answer'.
更好的解决方案更新的答案:
绑定到 class 列表,https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ngClass,可能是更好的方法:
示例:
<div class="mdl-textfield mdl-js-textfield mdl-text-field--floating-label"
[class.is-dirty]=" val != null && val != '' ">
或者对于 mdl-tabs:
<div class="mdl-tabs__panel"
[class.is-active]="val_is_active_tab">
或者对于 mdl-checkboxes:
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect"
[class.is-checked]="val == 1">
原回答:
对于我的项目,我的临时解决方案是放入一些非常非 angular2 的代码:
private thingsToDirty = [];
ngAfterViewChecked() {
for (let id of this.thingsToDirty) {
let el: any = document.getElementById(id);
if (el != undefined &&
el.parentNode.className.indexOf("is-dirty") == -1) {
el.parentNode.className += " is-dirty";
}
}
this.thingsToDirty.length = 0;
}
ngOnInit() {
this.something.getJSONfromServer().subscribe( data => {
this.thing = data;
this.thingsToDirty.push('thing_id');
});
}
我找到的最佳解决方案是使用指令。您可以在元素上调用 checkDirty()。
import { Directive, AfterViewInit, ElementRef, AfterViewChecked} from '@angular/core';
declare var componentHandler: any;
@Directive({
selector: '[mdl]'
})
export class MDL implements AfterViewInit {
constructor(private element: ElementRef) {
}
ngAfterViewInit() {
componentHandler.upgradeAllRegistered();
}
ngAfterViewChecked() {
let mdlField = this.element.nativeElement.MaterialTextfield;
if (mdlField) {
mdlField.checkDirty();
mdlField.checkValidity();
}
}
}
然后,在您的模板中,只需将此指令包含在 mdl 输入
的父级 div 中<div mdl class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--5-col mdl-cell--8-col-tablet mdl-cell--4-col-phone">
<label class="mdl-textfield__label" for="promoCode_{{inRibbon}}">Promo code</label>
<input class="mdl-textfield__input" type="text" id="promoCode" name="promoCode_{{inRibbon}}" [ngModelOptions]="{standalone: true}" [(ngModel)]="itemAvailabilityRequest.promoCode">
</div>