web-dev-qa-db-fra.com

Utilisation de méthodes d'assistance lors de la création de modèles avec Angular JS

Actuellement en train de convertir un site Web de son modèle précédent en Angular. Dans le processus de modélisation précédent que nous utilisions, nous avons pu appeler des méthodes d'assistance pour afficher correctement les données. Par exemple:

<script type="text/javascript">
$.views.helpers({
    parseDate: function (jsonDate) {
      if (jsonDate != null) {
        var newDate = Utils.PrettyDate(Utils.ConvertJsonDateToJsDate(jsonDate));
        return newDate;
      }
    }
});
</script>


<div class="post-info">
  <span class="posted-date">Posted {{ :~parseDate(CreatedDate) }}</span>
  &nbsp|&nbsp
  <span>{{ :ReplyCount }} Replies</span>
</div>

C'était très sympa. Essayer de trouver un moyen d'utiliser le même type de fonctionnalité avec Angular en ce qui concerne les modèles. Est-il possible de faire quelque chose de similaire? Si oui, comment?

19
yaegerbomb

Vous ajoutez simplement la méthode à votre contrôleur. Quelque chose comme ça:

<div class="post-info" ng-controller="MyCtrl">
    <span class="posted-date">Posted {{parseDate(CreatedDate)}}</span>
</div>

Ensuite, le contrôleur:

function MyCtrl($scope)
{
     $scope.parseDate = function(jsonDate) {
        //date parsing functionality
        return newParsedDate;
     }
}
32
dnc253

Si vous n'êtes intéressé que par l'affichage des données, alors comme pkozlowski.opensource l'a déjà mentionné, les filtres sont le "moyen angulaire" de formater les données pour l'affichage. Si le filtre de date existant n'est pas suffisant, je suggère un filtre personnalisé. Ensuite, votre code HTML sera plus "angulaire":

<span class="posted-date">Posted {{CreatedDate | dateFormatter}}</span>

La syntaxe ci-dessus indique clairement que vous formatez (uniquement).

Voici un filtre personnalisé:

angular.module('OurFormatters', []).
 filter('dateFormatter', function() {               // filter is a factory function
   return function(unformattedDate, emptyStrText) { // first arg is the input, rest are filter params
       // ... add date parsing and formatting code here ...
       if(formattedDate === "" && emptyStrText) {
            formattedDate = emptyStrText;
       }
       return formattedDate;
   }
 });

En encapsulant nos filtres/formateurs dans un module, il est également plus facile de les (ré) utiliser dans plusieurs contrôleurs - chaque contrôleur qui en a besoin injecte simplement OurFormatters.

Un autre avantage des filtres est qu'ils peuvent être enchaînés. Donc, si un jour vous décidez que dans certains endroits de votre application, les dates vides ne devraient rien montrer (être vides), tandis que dans d'autres endroits de votre application, les dates vides devraient afficher 'TBD', un filtre pourrait résoudre ce dernier:

<span class="posted-date">Posted {{CreatedDate | dateFormatter | tbdIfEmpty}}</span>

Ou votre filtre personnalisé peut prendre un ou plusieurs arguments (l'exemple ci-dessus prend en charge un argument):

<span class="posted-date">Posted {{CreatedDate | dateFormatter:'TBD'}}</span>
34
Mark Rajcok

En regardant le cas d'utilisation présenté, votre meilleur appel serait le filtre de date décrit ici: http://docs.angularjs.org/api/ng.filter:date En utilisant ce filtre, vous pourriez écrire:

{{CreatedDate | date}}

Le filtre mentionné est personnalisable afin que vous puissiez utiliser différents formats de date, etc.

De manière générale, les filtres sont très agréables pour encapsuler les fonctions d'assistance de la logique de formatage/de l'interface utilisateur. Plus d'informations sur la création de filtres ici: http://docs.angularjs.org/guide/dev_guide.templates.filters.creating_filters

Les filtres sont agréables et conviennent à de nombreux cas d'utilisation, mais si vous êtes simplement après avoir utilisé une fonction dans votre modèle, c'est possible. Définissez simplement une fonction dans une étendue et vous êtes prêt à l'utiliser directement dans votre modèle:

{{doSomething(CreatedDate)}}

où doSomething doit être défini sur une étendue (une étendue actuelle ou l'une des étendues parentes):

function MyCtrl($scope) {

    $scope.doSomthing = function(argument){
        //ui helper logic here
    }    
}
7