Défilement pleine page dynamique avec AngularJS 1.x

Sur ma station météo j’ai voulu implémenter un défilement pleine page (FullPage scrolling ou snap scroll).  La difficulté était de charger et de rafraichir dynamiquement les éléments affichés. Il existe probablement des solutions plus élégantes. Mais celle-ci répond à mon besoin.

Défilement pleine page

Pour le réaliser j’ai utilisé angular-snapscroll couplé à ses dépendances.

<div ng-controller="SnapCtrl as snapCtrl">
    <div ng-init="snapIndex=0" snapscroll="" fit-window-height="" snap-index="snapIndex" ng-swipe-up="snapIndex=snapIndex+1" ng-swipe-down="snapIndex=snapIndex-1" before-snap="snapCtrl.beforeSnap(snapIndex)">
      <div class="container">
        vue 1
      </div>

      <div class="container">
        vue 2
      </div>
    </div>
  </div>

Je maintiens un index qui sera récupéré par mon contrôleur. Voici le code, pour le moment, qui affiche l’index :

'use strict';

/**
 * @ngdoc function
 * @name App.controller:SnapCtrl
 * @description
 * # SnapCtrl
 * Controller of fullPage Scrolling
 */
angular.module('App')
  .controller('SnapCtrl', function($window, $location, $state) {

    var vm = this;

    vm.beforeSnap = function(snapIndex) {
      console.log('snapping to', snapIndex);
    };

  });

Routage des vues

Pour le routage j’utilise ui.router  et les vues multiples.

Nommage des vues :

  <div ng-controller="SnapCtrl as snapCtrl">
    <div ng-init="snapIndex=0" snapscroll="" fit-window-height="" snap-index="snapIndex" ng-swipe-up="snapIndex=snapIndex+1" ng-swipe-down="snapIndex=snapIndex-1" before-snap="snapCtrl.beforeSnap(snapIndex)">
      <div class="container">
        <div ui-view="vue1"></div>
      </div>

      <div class="container">
        <div ui-view="vue2"></div>
      </div>
    </div>
  </div>

Maintenant passons au routage :

angular.module('App')
  .config(function($routeProvider) {
    $routeProvider
      .otherwise({
      redirectTo: '/'
    });
  });

angular.module('App')
  .config(function($stateProvider) {
    $stateProvider
      .state('vue1', {
        url: "/",
        views: {
          "vue1": {
            templateUrl: 'views/vue1.html'
          },
          "vue2": {
            template: ''
          }
        }
      })
      .state('vue2', {
        url: "/vue2",
        views: {
          "vue1": {
            template: ''
          },
          "vue2": {
            templateUrl: 'views/vue2.html'
          }
        }
      });
  });

On affiche donc les vues 1 et 2 en fonction de la position du scroll.

Voici donc le contrôleur  qui va forcer la navigation.

'use strict';

/**
 * @ngdoc function
 * @name weathergFrontApp.controller:SnapCtrl
 * @description
 * # SnapCtrl
 * Controller of the App
 */
angular.module('App')
  .controller('SnapCtrl', function($window, $location, $state) {

    var vm = this;

    vm.sections = ['vue1', 'vue2']; //routes to load (vue1.html, etc)

    vm.beforeSnap = function(snapIndex) {
      console.log('snapping to', snapIndex);
      
      $state.go(vm.sections[snapIndex]);
    };


  });

Sources

Documentation angular-snapscroll

Documentation ui-router

https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

 

ng-pluralize et les nombres négatifs

Dans le cadre du développement du front-end de la station météo, je suis confronté à l’affichage des minutes d’ensoleillement gagnées ou perdues.

Pour cela, j’utilise la directive ng-pluralize  d’Angular :

<ng-pluralize count="main.suntimeDiff"
              when="main.suntimeDiff >=0 ? main.sunTimeLabel : main.negSunTimeLabel" >
</ng-pluralize>
    vm.negSunTimeLabel = {
      'other': '{} minutes de soleil'
    };

    vm.sunTimeLabel = {
      '0': 'pas de minute de soleil gagnée ou perdue',
      'other': '+{} minutes de soleil'
    };

J’ai donc deux tableaux de labels en fonction de l’état de ma variable.

Matomo encountered an error: Uncaught Error: Class "Piwik\Plugins\CustomVariables\CustomVariables" not found in /var/www/piwik/core/Tracker/TrackerCodeGenerator.php:98 Stack trace: #0 /var/www/piwik/plugins/SitesManager/API.php(159): Piwik\Tracker\TrackerCodeGenerator->generate() #1 [internal function]: Piwik\Plugins\SitesManager\API->getJavascriptTag() #2 /var/www/piwik/core/API/Proxy.php(255): call_user_func_array() #3 /var/www/piwik/core/Context.php(28): Piwik\API\Proxy->Piwik\API\{closure}() #4 /var/www/piwik/core/API/Proxy.php(158): Piwik\Context::executeWithQueryParameters() #5 /var/www/piwik/core/API/Request.php(272): Piwik\API\Proxy->call() #6 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/Request/Php.php(46): Piwik\API\Request->process() #7 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/Request/Php.php(18): WP_Piwik\Request\Php->call() #8 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/Request.php(63): WP_Piwik\Request\Php->request() #9 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik.php(1038): WP_Piwik\Request->perform() #10 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik.php(1205): WP_Piwik->request() #11 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/TrackingCode.php(16): WP_Piwik->updateTrackingCode() #12 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik.php(296): WP_Piwik\TrackingCode->__construct() #13 /var/www/thegtricks/wp-includes/class-wp-hook.php(324): WP_Piwik->addJavascriptCode() #14 /var/www/thegtricks/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters() #15 /var/www/thegtricks/wp-includes/plugin.php(517): WP_Hook->do_action() #16 /var/www/thegtricks/wp-includes/general-template.php(3066): do_action() #17 /var/www/thegtricks/wp-content/themes/twentyfifteen-child/footer.php(45): wp_footer() #18 /var/www/thegtricks/wp-includes/template.php(810): require_once('...') #19 /var/www/thegtricks/wp-includes/template.php(745): load_template() #20 /var/www/thegtricks/wp-includes/general-template.php(92): locate_template() #21 /var/www/thegtricks/wp-content/themes/twentyfifteen/archive.php(68): get_footer() #22 /var/www/thegtricks/wp-includes/template-loader.php(106): include('...') #23 /var/www/thegtricks/wp-blog-header.php(19): require_once('...') #24 /var/www/thegtricks/index.php(17): require('...') #25 {main} thrown (which lead to: Session must be started before any output has been sent to the browser; output started in /var/www/thegtricks/wp-includes/script-loader.php/2938)