使用listView和PouchDb的Ionic(v1)应用程序的问题

bnlyeluc  于 2023-04-18  发布在  Ionic
关注(0)|答案(1)|浏览(145)

In my Ionic app there is a listView with cards on which users can click. After clicking they should see a page with more details. All content is in a pouchDB database (and also remotely in Firebase). The code to generate this list is below:

<div class="card" ng-repeat="challenge in vm.challenges track by $index" ng-class="{'bounceInLeft': $index % 2 !== 0, 'bounceInRight': $index % 2 === 0}" ng-click="vm.goToChallenge(challenge)">
        <div class="item item-text-wrap">
            <div class="resource">
                <img ng-src="{{ challenge.resources[0].image }}" ng-attr-alt="{{ challenge.resources[0].caption }}" ng-srcset="{{ challenge.resources[0].srcset }}" ng-if="challenge.resources && challenge.resources[0].type === 'img'">
                <img ng-src="{{ challenge.resources[0].url | getYouTubeImage }}" ng-attr-alt="{{ challenge.resources[0].caption }}" ng-if="challenge.resources && challenge.resources[0].type === 'video'">
                <i class="ion-play" ng-if="challenge.resources && challenge.resources[0].type === 'video'"></i>
            </div>
            <p class="category">{{ challenge.categoryName }}</p>
            <p class="name">{{ challenge.name }}</p>
        </div>
        <div class="item footer item-divider">
            <div class="row">
                <div class="col col-50">
                    <i class="ion-calendar"></i> {{ challenge.seasonsObjects.join(', ') }}
                </div>
                <div class="col col-50">
                    <div>
                        <i class="ion-bookmark" ng-repeat="bookmark in (challenge.ranking + 1) | range track by $index"></i>
                    </div>
                    {{ challenge.rankingName }}
                </div>
            </div>
        </div>
    </div>

Unfortunately, on an iPhone 5 (iOS 10.2) and Samsung Galaxy S4 Mini (Android 4.4) clicking on a card does not show the details of that card (see image below). On an iPhone 5s and Samsung Galaxy S4 (Android 5) this works correctly (see second image below).

The function goToChallenge is defined as follows in the controller:

vm.goToChallenge = (challenge) => {
    NavigationService.go('home.challenge', {
        challenge: challenge._id
    });
};

The NavigationService has the following code:

angular.module('starter').factory('NavigationService', ['$window', '$q', 'ionic', '$state', '$ionicHistory', '$ionicLoading', '$ionicPopup', '$cordovaNativeAudio', '$cordovaSocialSharing', '$cordovaNetwork', '$ionicSideMenuDelegate', '$ionicNavBarDelegate', '$ionicTabsDelegate', NavigationService]);

function NavigationService($window, $q, ionic, $state, $ionicHistory, $ionicLoading, $ionicPopup, $cordovaNativeAudio, $cordovaSocialSharing, $cordovaNetwork, $ionicSideMenuDelegate, $ionicNavBarDelegate, $ionicTabsDelegate) {
let factory = {};
// Set root of history stack to the registration page with historyRoot: true
// Disable animation from slider to registration page to avoid weird transition
// in which the header bar pops down. This is because we do not have a header bar in the slider
factory.setRootAndGo = (state, params = {}) => {
    $ionicHistory.nextViewOptions({
        historyRoot: true,
        disableAnimate: true
    });
    factory.go(state, params);
};
factory.go = (state, params = {}) => {
    $state.go(state, params, {
        location: 'replace',
        reload: true
    });
};
factory.replace = (state, params = {}) => {
    $ionicHistory.currentView($ionicHistory.backView());
    factory.go(state, params);
};
factory.toggleMenu = () => $ionicSideMenuDelegate.toggleRight();
factory.showTabs = () => {
    $ionicTabsDelegate.showBar(true);
};
factory.hideTabs = () => {
    $ionicTabsDelegate.showBar(false);
};
factory.setTitle = (title) => $ionicNavBarDelegate.title(title);
factory.getParams = () => $state.params;
factory.getNavHistory = () => $ionicHistory.viewHistory();
factory.showLoading = (options) => $ionicLoading.show(options);
factory.hideLoading = () => $ionicLoading.hide();
factory.isWebView = () => ionic.Platform.isWebView();
factory.isOffline = () => factory.isWebView() && $cordovaNetwork.isOffline();
factory.goToWebPage = (url) => $window.open(url, '_system');
factory.shareFacebook = (text, img, url) => {
    let defer = $q.defer();
    $cordovaSocialSharing.shareViaFacebook(text, img, url)
        .then(defer.resolve, defer.reject);
    return defer.promise;
};
factory.shareTwitter = (text, img, url) => {
    let defer = $q.defer();
    $cordovaSocialSharing.shareViaTwitter(text, img, url)
        .then(defer.resolve, defer.reject);
    return defer.promise;
};
factory.playSound = (name) => $cordovaNativeAudio.play(name);
factory.alert = (title, text) => $ionicPopup.alert({
    title: title,
    template: text
});
return factory;
};

Does anyone know how to solve this issue, please? I have been looking for a few days now and can't figure out why. Thanks!

EDIT

When I check with chrome://inspect in a virtual device (via Genymotion), I get the following error in the console
TypeError: Object # has no method 'forEach' at ChallengeCtrl.vm.onAfterEnter (file:///android_asset/www/build/app.js:226:12) at m.$emit (file:///android_asset/www/lib/ionic/js/ionic.bundle.min.js:178:407) at Object.q.emit (file:///android_asset/www/lib/ionic/js/ionic.bundle.min.js:470:20592) at m (file:///android_asset/www/lib/ionic/js/ionic.bundle.min.js:470:19062) at HTMLElement.g (file:///android_asset/www/lib/ionic/js/ionic.bundle.min.js:470:18921) at Pf (file:///android_asset/www/lib/ionic/js/ionic.bundle.min.js:70:477) at HTMLElement.Of.d (file:///android_asset/www/lib/ionic/js/ionic.bundle.min.js:70:424) ionic.bundle.min.js:150
The onAfterEnter code block can be found below.

vm.onAfterEnter = () => {
    //let ionViewDOM = $window.document.querySelectorAll('.challenge.pane .scroll-content')[0];
    let ionViewDOM = $window.innerHeight - 43;  // innerHeight minus the heigh of the title bar
    let popovers = $window.document.querySelectorAll('.message-popover');
    popovers.forEach((popover) => {
        //popover.style.height = `${ionViewDOM.clientHeight}px`;
        popover.style.height = ionViewDOM + `px`;
        if (ionViewDOM.clientHeight < 450) {
            popover.classList.add('small-screen');
        } else if (ionViewDOM.clientHeight < 550) {
            popover.classList.add('medium-screen');
        } else {
            popover.classList.remove('small-screen');
            popover.classList.remove('medium-screen');
        }
    });

    let params = NavigationService.getParams();
    ChallengeService.get(params.challenge)
        .then((result) => {
            vm.challenge = result;

            switch (vm.challenge.status) {
                case 'accepted':
                    vm.challengeAccepted = true;
                    break;
                case 'completed':
                    vm.challengeCompleted = true;
                    break;
            }
            NavigationService.setTitle(vm.challenge.gardenType.name);
            vm.challengeLoaded = true;

            ChallengeService.listRandomAvailableForUser(params.challenge, vm.challenge.gardenType.challenges)
                .then((result) => vm.randomChallenges = result);
        });
};

When I check in an iPhone 5 simulator (via XCode) I get the following similar error
Error: popovers.forEach is not a function. (In 'popovers.forEach', 'popovers.forEach' is undefined)
So it has to do with the popovers. Could it be that $window.document.querySelectorAll('.message-popover') does not return anything? The div with the message-popover class are initially hidden on the page and only shown when a certain condition is met (with ng-show ).

wztqucjr

wztqucjr1#

似乎你的页面没有完全呈现在这些情况下,你达到foreach错误。你有没有尝试设置一个超时或类似的之前,执行querySelectorAll在页面上?

相关问题