html в моем приложении ionic 4 отображается перед вызовом моей функции - PullRequest
1 голос
/ 10 июля 2019

Я думаю, что у меня есть проблема с синхронностью.У меня есть массив матчей (т.е. спортивных приспособлений), которые я читаю из базы и отображаю на экране.Прежде чем я хочу отобразить их, я хочу сделать некоторые манипуляции со значениями, вызвав функцию.

Эта функция добавляет значение 'Y' к полю closestToToday на значение, которое соответствует названию, ближайшему к сегодняшней дате.,

Я уверен, что моя функция addClosestToTodayFlag работает правильно на основе журналов консоли, однако мой экран отображается до завершения функции.

Как явно заставить отображение данных на экране ждать завершения моей функции.

export class FixturesPage implements OnInit {

    public matches: Array<any>;
    constructor(private matchService: MatchService) {}

    ngOnInit(){
        this.matchService.getMatches().get().then(matchSnapshot => {
            this.matches = [];
            matchSnapshot.forEach(snap => {
                this.matches.push({
                    id: snap.id,
                    date: snap.data().date,
                    team: snap.data().team,
                    home: snap.data().home,
                    away: snap.data().away,
                    homeScore: snap.data().homeScore,
                    awayScore: snap.data().awayScore,
                    closestToToday: "N",
                });
                return false;
            });                
            this.addClosestToTodayFlag(this.matches);
         });        
    }
    private async addClosestToTodayFlag(fixtures: Array<any>)
    {   
        var today = Math.floor(Date.now()/1000);
        var fixtureClosestToToday = Math.abs(today - 
                 fixtures[0].date.seconds);

        fixtures[0].closetToToday = "Y";
        for (var i = 1; i < fixtures.length; i++)
        {
             var currentFixtureTimeToToday = Math.abs(today - 
                 fixtures[i].date.seconds);           
             /* 
              * If the difference in time between today and the 
                current fixture we are looping on is less than the 
              * difference in time of the current shortest gap then we 
                have a new fixture closest to Today
             */
             if (currentFixtureTimeToToday < fixtureClosestToToday)
                {
                    fixtureClosestToToday = currentFixtureTimeToToday;
                    fixtures[i].closetToToday="Y";
                    fixtures[i-1].closetToToday="N";    
                }
            else{
                fixtures[i].closetToToday="N";
              }            
        }
    }
}

1 Ответ

1 голос
/ 11 июля 2019

Когда вы помещаете совпадения в атрибут this.matches, представление немедленно обновляется.Таким образом, чтобы показать совпадения только после завершения вашей функции addClosestToTodayFlag, вы должны вызвать ее, дождаться ее и затем обновить массив matches.

Я бы сделал это, создав переменнуюсохраните «сырые» совпадения, а затем вызовите addClosestToTodayFlag с этим, передавая результат в this.matches, как только он завершится.

Из this.matches = []; в начале функции, создайте временную переменную, такую ​​как recievedMatches, нажмите на эту переменную и передайте ее addClosestToTodayFlag.

внутри addClosestToTodayFlag, верните обещание, содержащее данные результата, а затем отправьте данные результата в this.matches.

Update Здесь у вас есть пример кода (не проверено, но я думаю, что это должно работать).Я бы сказал, что вам даже не нужно делать addClosestToTodayFlag асинхронным или возвращать обещание, так как оно, похоже, не выполняет никаких асинхронных задач.

export class FixturesPage implements OnInit {
    public matches: Array<any>;
    constructor(private matchService : MatchService) {}

    ngOnInit() {
        this.matchService.getMatches().get().then(matchSnapshot => {
            let matches = [];
            matchSnapshot.forEach(snap => {
                matches.push({
                    id: snap.id,
                    date: snap.data().date,
                    team: snap.data().team,
                    home: snap.data().home,
                    away: snap.data().away,
                    homeScore: snap.data().homeScore,
                    awayScore: snap.data().awayScore,
                    closestToToday: "N"
                });
                return false;
            });
            this.matches = this.addClosestToTodayFlag(matches);
        });
    }

    private addClosestToTodayFlag(fixtures : Array<any>): Array<any> {
        var today = Math.floor(Date.now() / 1000);
        var fixtureClosestToToday = Math.abs(today - fixtures[0].date.seconds);

        fixtures[0].closetToToday = "Y";
        for (var i = 1; i < fixtures.length; i++) {
            var currentFixtureTimeToToday = Math.abs(today - fixtures[i].date.seconds);
            /*
             * If the difference in time between today and the
               current fixture we are looping on is less than the
             * difference in time of the current shortest gap then we
               have a new fixture closest to Today
            */
            if (currentFixtureTimeToToday < fixtureClosestToToday) {
                fixtureClosestToToday = currentFixtureTimeToToday;
                fixtures[i].closetToToday = "Y";
                fixtures[i - 1].closetToToday = "N";
            } else {
                fixtures[i].closetToToday = "N";
            }
        }

        return fixtures
    }
}
...