当前位置: 首页 > 知识库问答 >
问题:

Angular 2使用getter和setter将输入表单值与模型绑定

长孙兴德
2023-03-14

我想使用 getter 和 setter 将输入值绑定到模型。通过这种方式,我可以在写入输入时阻止和/或操纵输入的值。

例如,我想要输入框中的防止数字。所以,如果写“abc”all是可以的,那么如果我开始写一个数字,应该不会发生任何事情(对模型和输入的值)。问题是,使用以下代码,我可以在输入框中写入任何东西(但模型是正确的)。这意味着输入框的值并不真正代表我的模型。

注意:这个问题之外的原因是我想使用我的模型来验证表单,例如防止特定字符。我不想使用反应式表单,因为我想将我的验证保存在模型中,而不是组件中。还要注意,在实际场景中,我会有一个UserModel类,它的内部名称和其他字段及其验证。

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2><input type="text" [(ngModel)]="name"> {{name}}</h2>
    </div>
  `,
})
export class App {
  _name:string = 'ss';
  constructor() {
  }

  // In real scenario those 2 methods are in a separate class UserModel
  get name() {
    return this._name;
  }

  set name() {
    if ((new RegExp(/^[a-zA-Z]*$/).test(val))) {
        this._name = val;
    }
  }
}

共有3个答案

田兴怀
2023-03-14

您可以使用(ngModelChange)[ngModel]在更改时测试模型的内容。

正如你在这个 Plunker 中看到的,如果模型无效,它就不会改变。

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2><input #input type="text" [ngModel]="name" (ngModelChange)='valid(input.value)'> {{name}}</h2>
    </div>
  `,
})
export class App {
  name:string = 'ss';
  constructor() {
  }

  valid(value){
    if(value){ //<--- Your test here
      this.name = value;
    }
  }

}
莫誉
2023-03-14

根据@Günter Zöchbauer的回答,我制定了一个解决方案。它不是确定的,可能更抽象,但目前还可以。

export class App implements OnInit {
    @Input() userModel: UserModel = null;
    public _vm;

    constructor(private _changeDetectionRef: ChangeDetectorRef) {
    }

    /**
     * Initalize view model, it's important to keep names specular
     */
    ngOnInit() {
        this._vm = {
            name: this.userModel.name,
            surname: this.userModel.surname,
        };
    }

    /**
     * Helper for avoid detectchanges inside the modal, and reduce boilerplate. We could also ad an interface/type of the possibile field value, ie type fieldT= 'name' | 'surname';
     * @param field
     * @param val
     */
    protected updateModel(field, val: string): void {
        this._vm[field] = null;
        this._changeDetectionRef.detectChanges();
        this.userModel[field] = val;
        this._vm[field] = this.userModel[field];
        this._changeDetectionRef.detectChanges();
    }
}

在用户模型中:

....

    public get name(): string {
        return this.name';
    }

    public set name(val: string) {
        if ((new RegExp(/^[a-zA-Z]*$/).test(val))) {
            this.name = val;
        }
    }

在模板中:

<input type="text"  name="userName"  [ngModel]="_vm.name" (ngModelChange)="updateModel('name', $event)">
赫连琦
2023-03-14

如果您操作setter中的值,这可能会导致更改检测问题,因此ngModel不会接受更改并且不会更新

为了解决问题,您可以使用

export class App {

  _name:string = 'ss';

  constructor(private cdRef:ChangeDetectorRef) {}

  get name() {
    return this._name;
  }

  set name(value:String) {
    this._name = value + 'x';
    this.cdRef.detectChanges()
  }
}

如果您将该值重置为先前的值,您可能需要首先传递一个人工的不同值,否则更改检测将不会检测到更改,甚至< code>detectChanges()也不会更新输入。

  set name(value:String) {
    var oldVal = this._name;
    this._name = null;
    this.cdRef.detectChanges()
    this._name = oldVal;
    this.cdRef.detectChanges()
  }
 类似资料:
  • 问题:我希望每次子组件绑定到的对象中的属性发生变化时都能够调用一个函数。但是,setter只被调用一次,即使绑定的输入属性可以明显看到正在更新。 这一切都源于需要将子组件绑定到其父组件属性,该属性恰好是具有深度嵌套属性的复杂对象。我了解到,当对象中的嵌套属性发生更改时,Angular onChange 事件不会触发。因此决定改用吸气剂/二传手。然而,正如这个问题所见,使用吸气剂/设置器也不起作用。

  • 问题内容: 这是一个纯Python特定的设计问题: 和 Python让我们可以用任何一种方式来做。如果要设计Python程序,将使用哪种方法,为什么? 问题答案: 首选属性。这就是他们在那里的目的。 原因是所有属性在Python中都是公共的。以一两个下划线开头的名称只是警告,给定属性是实现细节,在将来的代码版本中可能会保持不变。它不会阻止您实际获取或设置该属性。因此,标准属性访问是访问属性的常规P

  • 问题内容: 我有两个Java类,一个包含getter和setter,另一个是驱动程序类。我需要来自驱动程序类中扫描程序的用户输入才能属于第一类中的getter。用户输入必须为double,因为它将用作getter中的公式。 问题答案: 真正最好的是将所有内容都放在一个类中,没有理由将一个类分成两个类,只是为了使获取器和设置器与其他类分开,这 没有任何意义 。我确实想知道您是否误解了您的作业。 现在

  • 假设我有一个类Things,它包含许多不同的实例变量。我为它们分别创建了单独的setter和getter方法。如果我想创建另一个存储things'class'的class2,那么为things类中的实例变量创建额外的setter和getter方法是很好的编码方法。另外,假设我有另一个使用class2的class3,那么重复setter和getter方法会产生高耦合吗?

  • 我可以使用以下代码轻松地将数据绑定到div或pre标记: 但是,我想尝试将此数据绑定到隐藏表单输入,我尝试了: 这将返回以下错误: 所以很明显,在使用ng模型时,我不能使用| json。角度文档仍然有点稀疏,我似乎无法找到如何正确分配它,即使我可以?谢谢:) 我需要将这个json数据加载到我的金字塔应用程序中,并将其分配到一个隐藏的表单字段中,这似乎是最好的方法,或者我应该以另一种方式来做?

  • 问题内容: 始终建议使用getter / setter访问私有变量。为什么最好将它们声明为public并对其进行访问。无论如何,我们正在使用getter和setter访问它? 问题答案: @mre的回答非常好,您的问题很重要。总结一下:您将对象的字段设置为私有,以控制其他对象使用它的方式。您的对象使用setter来: 限制和验证传递给设置器的数据 隐藏其内部数据结构(服务对其他对象感兴趣,而不是服