2

<input ...>当模板中带有标签的自定义指令在角度形式内时,我遇到了问题。

如果您在表单中声明输入,则编辑输入字段将按预期更改表单的属性,例如原始、触摸、有效等。

如果您在表单中声明自定义指令,比如说<ac2-string-input ...></ac2-string-input>它的模板包含一个输入,那么如果您编辑此输入的字段,它将不会改变表单的属性。

这是为什么?那是一个错误吗?有什么解决方法吗?

下面你有一个例子:

我们可以有一个表单组件,在app/form.component.ts

import { Component } from '@angular/core'

import { InputComponent } from './input.component'

@Component({
    selector: 'ac2-form',
    templateUrl: '<build path>/templates/form/form.html',
    directives: [InputComponent]
})

export class FormComponent {


    item: Object = {
       attr1: 'blah',
       attr2: 'another blah'
    }

    constructor(){}

    submit(){ console.log(this.item) }
}

带有模板templates/form/form.html

<form #f="ngForm" (ngSubmit)="submit()">
  <input type="text" name="attr1" [(ngModel)]="item.attr1"/>
  <ac2-string-input [obj]="item"></ac2-string-input>

  <button type="submit">Submit</button>
</form>

<div>
    Pristine? {{f.form.pristine}}
</div>

并且ac2-string-input指令在app/form/input.component.ts中定义

import { Component, Input } from '@angular/core'

@Component({
    selector: 'ac2-string-input',
    templateUrl: '<build path>/templates/form/input.html'
})

export class InputComponent {
    @Input() obj: Object;

    constructor(){}
}

带有模板templates/form/input.html

<input type="text" name="attr2" [(ngModel)]="obj.attr2"/>

如果我们加载表单,将会有两个文本字段,并且表单将是“Pristine”

形式

如果我们编辑“attr2”字段,表单将继续保持原始状态,就好像该字段没有绑定到表单一样!

现场编辑,形成原始

如果我们编辑“attr1”字段,表单将不会像预期的那样是原始的。

4

2 回答 2

3

我在 Angular 2 的 github 中打开了一个问题。

事实证明,如果我们希望我们的组件被识别为表单控件,我们需要实现ControlValueAccessor接口并将 ngModel 放在顶层。

这个Plunkr 展示了如何做到这一点。

感谢kara为我解决了这个问题。

于 2016-09-08T19:44:43.957 回答
0

内部input可能不被识别为表单的一部分,因为ac2-string-input它不是标准的 HTML 输入。

您可以通过输出表单的控件或值并查找attr2属性来验证这一点。如果它不存在,Angular甚至不知道它,因此更改该输入对表单的pristine状态没有影响。

为了使集成更容易,请考虑使用属性指令而不是组件。这会改变:

<ac2-string-input [obj]="item"></ac2-string-input>

<input type="text" [ac2StringInput]="item"/>

指令将类似于:

@Directive({
    selector: '[ac2StringInput]',
    host: {
        // onKeyup gets executed whenever the input receives input
        '(keyup)':'onKeyup($event)'
    }
})
export class InputComponent {
    constructor() {}

    /**
     * ac2StringInput to the outside refers to obj within this directive
     */
    @Input('ac2StringInput') obj:Object;

    /**Handle keyup*/
    onKeyup($event){}
}

form如果您想要更多地了解指令之外发生的事情,您甚至可以将整体作为输入传递给指令。

于 2016-09-05T03:45:59.810 回答