2017-07-07 55 views
1

我想用控制台(devtools)填充一个Angular 4+窗体。如何使用控制台devtools更新角度4+表单值?

这是我现在在做什么:

function fillForm(){ 
    let el = document.querySelector('input[ng-reflect-name="my_input"]'); 
    let elProbe = ng.probe(el); 
    elProbe._debugContext.component.value = 'new-value'; 
} 

一些引用我想使用(如果它可以帮助任何人):

+0

你在哪里打电话detectChanges? Angular非常懒惰,它想要一个踢:) – yurzui

回答

1

有两种选择。第一个是使用绑定到表单的组件属性,它需要手动更改检测触发。第二个是使用与输入相关的表单控件,并且不需要手动更改检测。

两者都不是更好。

对于第一个选项,请参阅@ yurzui的答案。下面是第二个选择答案 - 直接更新表单控件,而无需改变检测:

function fillForm(){ 
    let el = document.querySelector('input[ng-reflect-name="my_input"]'); 
    let elProbe = ng.probe(el); 

    const NgControlClassReference = elProbe.providerTokens.find((p)=>{ 
     return p.name === 'NgControl'; 
    }); 

    let directive = elProbe.injector.get(NgControlClassReference); 
    let control = directive.control; 

    control.setValue('some'); 
} 

在这种情况下,你不需要改变检测,因为当你在控制调用setValue它直接通知valueAccessor有关变化:

FormControl.prototype.setValue = function (value, options) { 
    ... 
    this._onChange.forEach(function (changeFn) { 
     return changeFn(_this._value, options.emitViewToModelChange !== false); }); 

其中changeFn处于setUpContorl功能添加订户:

control.registerOnChange((newValue: any, emitModelEvent: boolean) => { 
    // control -> view 
    dir.valueAccessor !.writeValue(newValue); 

直接调用存取writeValue,它反过来并将值写入输入:

export class DefaultValueAccessor implements ControlValueAccessor { 
    ... 

    writeValue(value: any): void { 
    const normalizedValue = value == null ? '' : value; 
    this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', normalizedValue); 
    } 

您也可能会发现这篇文章有用

Everything you need to know about debugging Angular applications

+0

你在'$ 0'上下文是什么? – leonardomerlin

+0

@leonardomerlin,它是'elProbe',我已经更新了细节 –

+0

我选择了@yurzui作为正确的答案,因为我没有发现在$ 0参考文件中放置了什么参考文件,而关于幻数“3” = /对不起。 – leonardomerlin

1

这样做的简单方法能使用核心令牌运行更改检测周期ApplicationRef

let el = document.querySelector('input[ng-reflect-name="my_input"]'); 
let elProbe = ng.probe(el); 
elProbe._debugContext.component.value = 'new-value'; 
elProbe.injector.get(ng.coreTokens.ApplicationRef).tick() 

您还可以看看集成测试

https://github.com/angular/angular/blob/master/packages/forms/test/template_integration_spec.ts#L28-L30

我觉得这种方式,我们检查我们的组件如何与NgModel不直接调用API的内部NgModel指令。

如果不调用变化检测,我们也可以将下面的代码来模拟用户操作

let valueAccessor = elProbe.injector.get(elProbe.providerTokens 
         .find(x =>x.name === 'DefaultValueAccessor')); 

el.value = 'some'; 
valueAccessor.onChange('some'); 

但它看起来很奇怪

+0

工程就像一个魅力!谢谢! – leonardomerlin

+0

如果您直接更新控件,则不需要更改检测 –

+0

@Maximus Angular以这种方式工作,所以我认为它不正确 – yurzui