如何让 Material Calender 的 Date Picker Filter 方法与 Observables 一起工作

Jac*_*ack 5 datepicker angular-material angular

我在我的项目中使用了一个 Angular Material Date Picker 应用程序,它是一个预订表格。我想要的是让用户通过Date Picker选择日期。日期选择器将有一个过滤器,显示哪些日期是开放的,哪些不是。为了让日期选择器知道哪些日期可用,它必须调用我的一项服务,该服务返回一个Observable。这是我的日期选择器的 HTML 代码:

<mat-form-field>
  <label>
    <input matInput [matDatepickerFilter]="dateFilter" required [matDatepicker]="picker" placeholder="Choose a date"
           formControlName="date">
  </label>
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Run Code Online (Sandbox Code Playgroud)

和日期过滤器():

dateFilter = (d: Date): boolean => {
    if(monthIsSame(d) {
        ..// have a return statement that process a global variable: 'month: Day[]'
    } else {
        // the user hit the arrow at the top that switches months
        //
        // have a process that sets the 'month' variable to a new array of Days that was gotten 
        // through a RESTful api in one of my services.
        // Somehow there must be a loading wheel here until the result from my server comes back and
        // month is set to the new current month, and then a return statement that process a month
    }
};
Run Code Online (Sandbox Code Playgroud)

问题是每次用户切换月份时,日历必须从后端服务器加载月份可用性,但服务器的代码返回一个 Observable。日历必须以某种方式显示一个加载轮,直到值从 observable 的 subscribe 方法返回,并且日历将填充可用日期。

非常感谢任何帮助,如果我是从完全错误的方式来解决这个问题的,请告诉我。谢谢!


编辑:

注意:当我将过滤器的返回类型更改为Observable<boolean>它时,它会将所有日期设置为可用。

我找到了以下帖子。当用户切换几个月并运行我的http请求并将结果加载到局部变量时,是否有可能以某种方式调用回调函数。唯一的问题是日历必须以某种方式显示加载轮,直到回调函数完成。

pdu*_*gic 6

如何让 mat-calendar 异步刷新日期过滤器:

解决方案是在dateFilter从服务器检索数据时设置为新值。Angular 正在其更改检测中检查此值并刷新视图。

// initial filter function always returns true
dateFilter = (date: Date): boolean => {return true;}

constructor( ... ) {

  this.myDataObs.subscribe( () => {
    // set filter function when new data is available
    this.dateFilter = (date: Date): boolean => { 
      return filterBasedOnDataFromServer(date);
    };
  });
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*iro 3

我将尝试制定一个高级计划,看看是否有帮助。

您将需要一个服务来在自定义标头(稍后详细介绍)和页面组件(您拥有该dateFilter方法)之间传递数据。我们称这个服务为OpenDatesService。我认为它不应该在模块中提供,因为您并不总是需要它,但它必须至少具有与您的页面一样长的生命周期,因此理想情况下它是在您的页面中提供的。在这种情况下,您应该能够在页面组件和自定义标头中注入,并且这些将是相同的实例。

因此,创建一个自定义标头。您完全可以从 Angular Material 中获取一个,或者从 docs 中获取示例。我将使用这个例子来解释。在标头的上一个/下一个回调中,您不会立即调用日历(_dateFormats在示例中),而是首先启动网络请求,用微调器替换箭头(使用标志和一些ngIfs),然后仅重新启用网络请求返回后的按钮。是的,这是异步的(observables/promise/async-await),但此时,您不会被迫同步执行任何操作。因此,在网络请求完成之后,但仍然在调用日历的 prev/方法之前,将开放日期的数据传递给OpenDatesService,即。它应该有一个方法 sg。喜欢updateOpenDates。然后您可以调用日历的 prev/next 方法。

调用日历的 prev/next 方法后,您的页面组件dateFilter将很快被调用。但是这个时候,OpenDatesService已经有了开放日期的数据,并且服务被注入到页面中,所以在里面dateFilter你就可以同步获取它,并根据它同步返回结果到日历。

总结一下,有2个技巧:

  • 将网络请求的异步性质从dateFilter日历使用的方法移至标头的单击处理程序
  • dateFilter在页面的方法和标题之间传递数据。

编辑:

现在我认为,您甚至不需要该服务在自定义标头和页面组件之间传递数据。这是因为自定义标头是在页面组件的模板中实例化的,其中标头可以使用 向页面传递数据@Output,并且页面可以将其存储在一些本地字段中,这些字段也可以通过该dateFilter方法访问。