【问题标题】:How to load multiple data via service and wait for it in Angular2如何通过服务加载多个数据并在Angular2中等待
【发布时间】:2017-06-19 14:20:54
【问题描述】:

我在我的项目中使用 Ionic 2 和 Angular 2。在根组件中,您可以单击“添加”按钮通过复杂的表单和大量预先提供的数据添加新报告(有些选择是从 sqlite 数据库获取的数据提供的) 现在在我的“CreateReportComponent”中,我有以下构造函数来加载数据并将其分配给本地数组变量:

selectEmployeeOptions: Employee[];

constructor(private dbService: DatabaseService) {
  dbService.getAllEmployees().then(employees => {
      this.selectEmployeeOptions = employees;
  });

  // load more data like tasks etc.
});

但是当我想在我的组件中修改这些数据时,数组是空的。我尝试在 ngOnInit() 中执行此操作,但这似乎还为时过早。

在组件显示之前,我想这样做:

  dbService.getAllEmployees().then(employees => {
      this.selectEmployeeOptions = employees;

      // modify data
      this.selectEmployeeTitleOptions = employees.map((item) => {
         return item.title;
      });
      console.log(JSON.stringify(this.selectEmployeeTitleOptions)) // --> empty
  });

但是 selectEmployeeTitleOptions 是空的...

databaseService 中的函数如下所示:

getAllEmployees(): Promise<Emplyoee[]> {
  let query = "SELECT * FROM employees";
  let employeeList = [];
  this.database.executeSql(query, []).then((data) => {
     if(data.rows.length > 0) {
       let e = new Employee();
       e.id = data.rows.item(i).id;
       e.firstname = data.rows.item(i).firstname;
       e.lastname = data.rows.item(i).lastname;
       employeeList.push(e);
     }
  }, (error) => {
     // handle error
  });
  return Promise.resolve(employeeList);
}

我读到有解决模式 (https://blog.thoughtram.io/angular/2016/10/10/resolving-route-data-in-angular-2.html) 但我需要拨打多个电话,而不仅仅是示例中的联系人。

那么问题来了:如何等待多次调用数据库?

【问题讨论】:

    标签: sqlite angular typescript ionic2 resolver


    【解决方案1】:

    我觉得这里出了点问题

    getAllEmployees(): Promise<Emplyoee[]> {
      let query = "SELECT * FROM employees";
      let employeeList = [];
      this.database.executeSql(query, []).then((data) => {
         if(data.rows.length > 0) {
           let e = new Employee();
           e.id = data.rows.item(i).id;
           e.firstname = data.rows.item(i).firstname;
           e.lastname = data.rows.item(i).lastname;
           employeeList.push(e);
         }
      }, (error) => {
         // handle error
      });
      return Promise.resolve(employeeList);
    }
    

    首先return Promise.resolve(employeeList); 将返回空数组,因为它是异步进程。 你需要遍历data.rows,然后像这样格式化返回数据。

    getAllEmployees(): Promise<Employee[]> {
      let query = "SELECT * FROM employees";
      return this.database.executeSql(query, []).then((data) => {
        let arr = [];
        for(let i = ; i < data.rows.length; ++i) {
          let emp = data.rows.item(i);
          let e = new Employee();
          e.id = emp.id;
          e.firstname = emp.firstname;
          e.lastname = emp.lastname;
          arr.push(e);
        }
        return arr;
      });
    }
    

    注意.then() 返回一个承诺对象。

    【讨论】:

    • 谢谢。我试过这个但得到一个错误:TypeError: data.rows.map is not a function
    • 能否提供data.rows 值(登录到控制台)?
    • 当然。 data.rows 是 {"length":3} 而 data 是 {"rows":{"length":3},"rowsAffected":0}
    • 如何循环遍历所有行
    • 截屏然后上传到某处
    【解决方案2】:

    您正在寻找的是返回 Observable 的 forkJoin 方法,您应该切换到该方法而不是使用 Promises,以供参考为什么要进行此检查 here。

    来自其 GitHub 页面的关于 fork join 的简短信息:

    并行运行所有可观察序列并收集它们的最后一个元素。

    这样您就可以安全地向您的 API 发出并行请求。

    有关 forkJoin 的更多信息,请转到here。

    此外,您应该使用前面提到的 ngOnInit 调用服务。有关 Angular 2 生命周期挂钩的更多信息,请参阅docs。

    【讨论】:

    • 我会尝试接受@tiep-phan 的回答。但我会利用你最后的建议。谢谢:)
    【解决方案3】:

    你可以使用 Promise.all https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

    你把所有的 Promise 都推送到一个数组中,然后去

        let foo : [Promise<Emplyoee[]>,Promise<void>] = [getAllEmployees(), method2()];
        Promise.all(foo).then((results:any[]) => {
           let employeearray: any = results[0];
           /* and on an on */
         });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-26
      • 1970-01-01
      • 2016-07-27
      • 2022-01-15
      • 2017-05-12
      • 2017-12-27
      • 2022-11-29
      相关资源
      最近更新 更多