【问题标题】:Ionic/Angular 2 component event emitter not updating viewIonic/Angular 2 组件事件发射器不更新视图
【发布时间】:2016-09-01 14:01:07
【问题描述】:

我目前正在编写一个 Ionic 2 应用程序并创建了以下自定义组件:

import {Component, EventEmitter} from 'angular2/core';
import {Button, Icon, Item} from 'ionic-angular';
import {DatePicker} from 'ionic-native';
import {HSDatePipe} from '../pipes/custom-dateformat.pipe';

@Component({
    selector: 'date-picker',
    directives: [Button, Icon, Item],
    inputs: ['date', 'dateFormat', 'mode'],
    outputs: ['onUpdate'],
    pipes: [HSDatePipe],
    template: `<button clear (click)="selectDate()">
        {{date | hsDate:dateFormat}}
    </button>`
})
export class HSDatePicker {

    date:any;
    dateFormat:any;
    label:string;
    mode:string;
    onUpdate:any = new EventEmitter();

    constructor() {
    }

    selectDate() {
        let self:any = this;
        let previousDate:any = self.date;

        DatePicker.show({
            date: new Date(self.date),
            mode: self.mode
        })
        .then(
            (date:any) => {
                if (!date) {
                    date = previousDate;
                }
                self.onUpdate.emit(date);
            },
            err => {
                console.log('error -', err);
            }
        );
    }

}

在调用此组件的页面上,我将其包含在页面中,如下所示:

<date-picker item-right [date]="period.dateEnd" [dateFormat]="'HH:mm'" [mode]="'time'" (onUpdate)="dateChange($event, 'dateEnd')"></date-picker>

dateChange 函数如下所示:

dateChange(e, selector) {
    let newDate = moment(e);
    this.transactionFilter[selector] = newDate;
}

当我使用该组件选择一个新日期时,该函数按我的预期调用,并且 transactionFilter 对象被更新。但是,视图不会更新,它仍然会在页面上显示旧日期,直到我单击按钮或聚焦输入等。

我认为问题与 DatePicker 插件或承诺有关,因为如果我像这样更改 selectDate() 函数,它会更新正常。

selectDate() {
    let self:any = this;
    self.onUpdate.emit(new Date());
}

有没有办法强制更新视图,或者我应该以某种不同的方式进行更新?

感谢您的帮助。

编辑:主页模板

@Page({
    template: `
    <ion-content>
        <ion-toolbar primary class="subheader">
            <ion-title>Transaction Viewer Filter</ion-title>
        </ion-toolbar>
        <ion-list>
            <ion-item>
                <ion-icon name="calendar" item-left></ion-icon>
                From
                <date-picker item-right [date]="transactionFilter.fromDate" [dateFormat]="'DD/MM/YYYY HH:mm'" [mode]="'datetime'" (onUpdate)="dateChange($event, 'fromDate')"></date-picker>
            </ion-item>
            <ion-item>
                <ion-icon name="calendar" item-left></ion-icon>
                To
                <date-picker item-right [date]="transactionFilter.toDate" [dateFormat]="'DD/MM/YYYY HH:mm'" [mode]="'datetime'" (onUpdate)="dateChange($event, 'toDate')"></date-picker>
            </ion-item>
            <ion-item>
                Count: {{count}}
            </ion-item>
        </ion-list>
        <ion-row>
            <ion-col>
                <button class="close-modal" (click)="close()" danger block>Close</button>
            </ion-col>
            <ion-col>
                <button class="save-modal" (click)="save()" favorite block>Save</button>
            </ion-col>
        </ion-row>
    </ion-content>`,
    directives: [HSDatePicker]
})

【问题讨论】:

  • 您使用的是哪个版本的 ionic beta?
  • ionic -v 显示 2.0.0-beta.25
  • 在您的项目路由中键入ionic info 以获取该项目的详细信息。我认为ionic -v 是 CLI 版本
  • 抱歉,Ionic Framework 版本是 2.0.0-beta.6。 Ionic App lib 版本为 beta 15。

标签: cordova datepicker angular ionic2 angular2-components


【解决方案1】:

我认为这是因为 Angular2 根据引用而不是值来检测更改。如果检测到新的日期实例,则将更新视图。如果它是同一个实例但它的内容被更新了,则视图不会被更新。

我会像这样重新创建一个新日期:

DatePicker.show({
  date: new Date(self.date),
  mode: self.mode
})
.then(
  (date:any) => {
    if (!date) {
      date = previousDate;
    }
    self.onUpdate.emit(new Date(date.getTime()));
  },
  err => {
    console.log('error -', err);
  }
);

编辑

您可以尝试在区域中执行您的处理:

export class HSDatePicker {

    date:any;
    dateFormat:any;
    label:string;
    mode:string;
    onUpdate:any = new EventEmitter();

    constructor(private ngZone:NgZone) { // <-------
    }

    selectDate() {
      this.ngZone.run(() => { // <------
        let self:any = this;
        let previousDate:any = self.date;

        DatePicker.show({
            date: new Date(self.date),
            mode: self.mode
        })
        .then(
            (date:any) => {
                if (!date) {
                    date = previousDate;
                }
                self.onUpdate.emit(date);
            },
            err => {
                console.log('error -', err);
            }
        );
      });
    }

【讨论】:

  • 您好,我尝试了您的解决方案,但不幸的是视图仍未更新。
  • 我认为你应该在一个区域内执行事情。我相应地更新了我的答案......
  • 同样的问题:(它更新了dateChange()里面的对象很好,只是视图没有更新。我也尝试将this.transactionFilter[selector]设置为new Date()并忽略了传入的参数,但它还是一样的。
  • 你能告诉我模板中对应的块吗?谢谢!
  • 啊,你指出了我正确的方向,ngZone 工作了,非常感谢!我会接受你的回答,然后发布我所做的。基本上我不得不移动 ngZone.run 函数运行的地方。
【解决方案2】:

我像这样更改了selectDate() 函数,它现在可以工作了。感谢 Thierry 和这篇文章 ionic2-camera-demo 为我指明了正确的方向。

selectDate() {

        let self:any = this;
        let previousDate = self.date;

        DatePicker.show({
            date: new Date(self.date),
            mode: self.mode
        })
        .then(
            (date:any) => {
                if (!date) {
                    date = previousDate;
                }
                this.ngZone.run(() => {
                    self.onUpdate.emit(date);
                });
            },
            err => {
                console.log('error -', err);
            }
        );

    }

【讨论】:

    猜你喜欢
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    相关资源
    最近更新 更多