我对AngularJS有一个问题,我似乎无法修复,因为我不知道我做错了什么。
版本
AngularJS:1.6.1
角度材料:1.1.1
问题
我正在使用AngularJS组件和过滤器构建datetimepicker。
当我点击显示的日期(通过{{ $ctrl.model | date:'dd-MM-yyyy HH:mm' }}u
格式化)时,会打开一个带有自定义日期时间戳的角度材质弹出窗口,并显示一些更改日期的选项。用户单击“确认”后,日期将传递给我的组件(打开对话框的日期),并将新日期分配给模型this.model = newDate.getMomentDate();
。在此之后,我希望视图日期也会更新和格式化。但它只是更新而不是格式化。
预期结果: 28-02-2016 00:00u
结果: 2016年2月28日星期日00:00:57 GMT + 0100u
二手组件
为了实现这个功能,我使用了一些角度组件:
{{ $ctrl.model | date:'dd-MM-yyyy HH:mm' }}u
)转换为time.html并管理对话框(datetimepicker.ts)的组件为time.html
<date-time-picker title="pick your time"
model="$ctrl.time.meeting">
</date-time-picker>
datetimepicker.component.ts
绑定
bindings: {
model: "=", //Angular ng-model is automatically updated this way
title: "@?"
},
transclude: true,
controller: DateTimePickerController
Picker回调
showPicker(): void {
this.$mdDialog.show(this.datePickerDialog).then((newDate: DateTimePickerModel) => {
this.model = newDate.getMomentDate();
}, function () {
//Cancel
});
}
datepicker.html
<md-button ng-click="$ctrl.showPicker()" aria-label="open dialog">
{{ $ctrl.model | date:'dd-MM-yyyy HH:mm' }}u
</md-button>
DateTimePickerModel.ts
export class DateTimePickerModel {
constructor(public day: string,
public month: string,
public year: string,
public hour: string,
public minute: string,
public second: string) {
}
/**
* Returns the number of days of the month
* @return number
*/
getDaysInMonth(): number {
return moment(this.year + '-' + this.month).daysInMonth();
}
/**
* Formats the property values to a moment date
* @return {Moment}
*/
getMomentDate(): Moment {
return moment(
this.year + "-" + this.month + "-" + this.day + "T" +
this.hour + ":" + this.minute + ":" + this.second,
moment.ISO_8601);
}
}
我遗漏了datetimepickerdialog.controller.ts,因为DateTimePickerModel的一个实例被传递给控制器,它与2路绑定或ng模型无关(我不期望有控制器中可能导致问题的任何事情。)
我试过
我尝试使用$scope.$apply()
bercause我期望Angular没有看到变化。但是使用$scope.$apply()
我收到错误'Digest is already running'
。
我还尝试用单向绑定("="
)替换组件("<"
)的双向绑定,并将日期返回到time.component.ts中功能。在time.component.ts
中,我会使用新日期更新ng-model
。然而,这给了我相同的结果。
我找到了一个有效的workarround,但这违背了Angular过滤器的全部目的。为此,我通过get方法操作控制器内的模型。这也适用于发现更改时的更新。但是我通过视图操作来污染我的控制器。 (我不建议这样做!)
datetimepicker.component.ts
/**
* Formats the model and return the formatted version.
* - An Angular filter didn't work. It was somehow only called once, if the model changed it didn't format it -
* @return {string}
*/
get formattedModel(): string {
return moment(this.model).format('DD-MM-YYYY HH:mm');
}
datetimepicker.html
<md-button ng-click="$ctrl.showPicker()" aria-label="open dialog">
{{ $ctrl.formattedModel }}u
</md-button>
我想不出任何其他选项,因为Angular会在每个$digest
周期运行页面上的每个过滤器,因为它不知道ng-model对哪些过滤器有效。 (每次更改都可能对页面产生影响,因此每个周期都需要重新评估每个过滤器。)
任何可以帮助我的人?
答案 0 :(得分:0)
这很一般,因为你的问题非常详细。
首先,Angular 1.6尚未与Material 1.1.1兼容,因此我首先尝试使用Angular 1.5,并查看这是否无法解决您的问题。 https://github.com/angular/material/issues/10111
其次,如果您正在制作使用模型的组件,请考虑直接遵循实际使用ng-model的模式,如下所述:https://docs.angularjs.org/api/ng/type/ngModel.NgModelController
第三,为什么不将特定问题与测试隔离开来,然后你就会知道它是组件中的某些东西还是你使用模态的方式。例如,用材料日期时间选择器替换时间选择器组件。如果这样可行,那么您就知道问题出在组件中并且与模态无关。