【问题标题】:Get value from dynamically generated inputfield [closed]从动态生成的输入字段中获取值[关闭]
【发布时间】:2022-01-24 06:24:02
【问题描述】:

我有一个对象:

schedule = {
      'Monday': { morning: { from: "9:00", to: "12:00" }, afternoon: { from: "15:00", to: "17:00" } },
      'Tuesday': { morning: { from: "9:00", to: "12:00" }, afternoon: { from: "15:00", to: "17:00" } },
      'Wednesday': { morning: { from: "9:00", to: "12:00" }, afternoon: { from: "15:00", to: "17:00" } },
      'Thursday': { morning: { from: "9:00", to: "12:00" }, afternoon: { from: "15:00", to: "17:00" } },
      'Friday': { morning: { from: "9:00", to: "12:00" }, afternoon: { from: "15:00", to: "17:00" } },
    };

我将 schedule 对象转换为一个数组,以便 Angular 可以通过这种方式对其进行迭代:

getScheduleArray() {
    let profile = this.profile;
    var days = Object.keys(profile.schedule);
    var array: { day: string; schedule: any; }[] = [];
    days.map(function (key) {
      return array.push({ day: key, schedule:profile.schedule[key] });
    });
    return array;
  }

在我的 Angular 应用程序中,我有许多以这种方式动态生成的不同输入字段:

<div class="p-2" *ngFor="let day of getScheduleArray()">
    <p><b>{{day.day}}</b></p>
    <div class="row">
        <p class="col">Morning</p>
        <div class="col"><input class="form-control" type="text" placeholder="From" [(value)]="day.schedule.morning.from" (input)="updateSchedule(day.day, 'morning', 'from', $event)"></div>
        <div class="col"><input class="form-control" type="text" placeholder="To" [(value)]="day.schedule.morning.to" (input)="updateSchedule(day.day, 'morning', 'to', $event)"></div>
    </div>
    <div class="row">
        <p class="col">Afternoon</p>
        <div class="col"><input class="form-control" type="text" placeholder="From" [(value)]="day.schedule.afternoon.from" (input)="updateSchedule(day.day, 'afternoon', 'from', $event)"></div>
        <div class="col"><input class="form-control" type="text" placeholder="To" [(value)]="day.schedule.afternoon.to" (input)="updateSchedule(day.day, 'afternoon', 'to', $event)"></div>
    </div>
</div>

要更新时间表,我使用以下方法:

updateSchedule(day: string, partOfDay: string, startOrFinish: string, event: any) {
    this.profile.schedule[day][partOfDay][startOrFinish] = event.target.value;
  }

有没有更好的方法来获得相同的结果?

【问题讨论】:

    标签: javascript html angular typescript


    【解决方案1】:

    一些我会改进的地方:

    1. 根本不要使用var。虽然它可以工作,但它可以支持旧版 JS 应用程序,您应该始终使用 constletlet 用于您计划稍后更新的变量,例如计数器。 const 用于永远不会改变值的变量,例如时间变量。

    2. 尽可能使用const。大多数时候,我们需要一个时间变量来使我们的代码更具可读性。 typescript 编译器足够智能,可以搜索和内联const 变量,以使我们的代码更快。如果您不打算更新变量,请使用 const

    3. 正确使用map 功能谓词。在这种情况下,您正在创建一个副作用,这与编写 for 没有什么不同(在这种情况下会更好)

    你正在做的:

        var array: { day: string; schedule: any; }[] = [];
        days.map(function (key) {
          return array.push({ day: key, schedule:profile.schedule[key] });
        });
        return array;
    

    如果你这样做,效果会更好:

        var array: { day: string; schedule: any; }[] = [];
        for(let key of keys) {
          array.push({ day: key, schedule:profile.schedule[key] });
        });
        return array;
    

    正确使用映射谓词,您不应该改变外部数组,您可以这样做:

      return keys.map(key => ({ day: key, schedule:profile.schedule[key] }))
    

    map 的作用是它接受一个原始数组并通过每个元素运行一个函数并将其聚合到最终结果。

    1. 缓存您的结果,这会使您的应用程序变慢。当我们有点懒惰并且我们只是将函数的值放入角度模板中时,我们冒着创建新对象的风险(每次调用函数时都会创建数组)。这最终导致更改检测器运行多次并每次都在函数内运行代码,因为您总是返回一个数组的新实例(具有相同的内容,这就是我们没有注意到 GUI 中的变化的原因)

    为此,您只需在 ngOnInit 上运行代码并将其存储在组件的属性中:

    @Component({...})
    export class YourComponent implements OnInit {
      yourSchedule: Array<{ day: string; schedule: any; }>
      ngOnInit() {
        this.yourSchedule = this.getScheduleArray()
      }
    }
    

    这样,您的代码运行一次,整体速度更快。

    1. 最后:使用反应形式。您的代码按原样工作,但您几乎无法控制进行输入验证。您需要修改您的getScheduleArray() 并以某种方式返回带有所需验证器的FormGroupFormArray。这完全是可选的,因为它取决于您项目的要求,但我只是想展示您可以打开它的其他内容。 :)

    总的来说:很棒的工作:)!

    【讨论】:

      【解决方案2】:

      据我了解,您只是在更新计划对象的值。如果您使用的是 Angular 2+,那么我建议您通过将 Forms Module 导入组件模块来使用 [(ngModel)] dire。

      如果需要将数据写入 this.profile.schedule 对象的属性中,那么代码将如下所示:

      ...
      <div class="col"><input class="form-control" type="text" placeholder="From" [(ngModel)]="profile.[day.day].schedule.morning.from" /></div>
      ...
      

      但是,请注意这里有双向数据绑定。初始值取自对象并写入对象。 details

      因此,可能值得更改您创建的值数组中的数据。单击提交按钮时,将更改的数据写入主对象

      【讨论】:

      • 我在使用 ngModel 时遇到了问题,我会尝试让您知道!
      猜你喜欢
      • 1970-01-01
      • 2015-02-12
      • 2013-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多