Излучатель событий компонента Ionic/Angular 2 не обновляет вид

В настоящее время я пишу приложение 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]
})

person Daniel Hutton    schedule 06.05.2016    source источник
comment
какую версию ionic beta вы используете?   -  person Will.Harris    schedule 06.05.2016
comment
ionic -v отображает 2.0.0-beta.25   -  person Daniel Hutton    schedule 06.05.2016
comment
В маршруте вашего проекта введите ionic info, чтобы получить подробную информацию об этом проекте. Я думаю, что ionic -v - это версия CLI   -  person Will.Harris    schedule 06.05.2016
comment
Извините, версия Ionic Framework 2.0.0-beta.6. Версия Ionic App lib — бета-версия 15.   -  person Daniel Hutton    schedule 06.05.2016


Ответы (2)


Я думаю, это потому, что 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);
            }
        );
      });
    }
person Thierry Templier    schedule 06.05.2016
comment
Привет, я попробовал ваше решение, но, к сожалению, представление все еще не обновляется. - person Daniel Hutton; 06.05.2016
comment
Я думаю, что вы должны выполнять вещи в пределах зоны. Я обновил свой ответ соответственно... - person Thierry Templier; 06.05.2016
comment
Та же проблема :( он отлично обновляет объект внутри dateChange(), просто представление не обновляется. Я также пытался просто установить this.transactionFilter[selector] на new Date() и проигнорировал входящий параметр, но это все равно было то же самое. - person Daniel Hutton; 06.05.2016
comment
Не могли бы вы показать мне соответствующий блок в шаблоне? Спасибо! - person Thierry Templier; 06.05.2016
comment
Я обновил свой вопрос с помощью шаблона, вы это имели в виду? Спасибо! - person Daniel Hutton; 06.05.2016
comment
Спасибо! Поддерживает ли средство выбора даты двустороннюю привязку? Что-то вроде: <date-picker item-right [(date)]="transactionFilter.fromDate" [dateFormat]="'DD/MM/YYYY HH:mm'" [mode]="'datetime'" (onUpdate)="dateChange($event, 'fromDate')"></date-picker> - person Thierry Templier; 06.05.2016
comment
Ах, вы указали мне правильное направление, и ngZone сработал, большое спасибо! Я приму ваш ответ, а затем опубликую, что я сделал. По сути, мне пришлось переместиться туда, где выполнялась функция ngZone.run. - person Daniel Hutton; 06.05.2016

Я изменил функцию selectDate() вот так, и теперь она работает. Спасибо Тьерри и этому сообщению 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);
            }
        );

    }
person Daniel Hutton    schedule 06.05.2016