Title: Dades JSON i AngularJS
Course: CFGS - Desenvolupament d'aplicacions web > Section: Desenvolupament d'aplicacions mòbils

Serveis RESTful

JSON

JSON (prové de l'acrònim JavaScript Object Notation) és un standard obert basat en text per a l'intercanvi de dades i que pot ser directament llegit per humans, en realitat deriva del llenguatge Javascript, de la seva metodologia per representar objectes simples i llistes associatives, que n'anomena objects.

Tot i la seva relació amb JavaScript, aquesta representació de dades, té implementacions en diversos llenguatges de programació i la seva representació en MIME és application/json i els arxius que representen estructures en aquest format utilitzen la extensió .json

El format JSON s'utilitza habitualment per serialitzar i transmetre dades estructurades en una connexió de xarxa.

Exemple en JSON:

{"estudiants":[
    {"nom":"David", "cognom1":"Vidal", "cognom2":"Soler"},
    {"nom":"Roser", "cognom1":"Puig", "cognom2":"Ferrer"},
    {"nom":"Pere", "cognom1":"Serra", "cognom2":"Martí"}
]}


JSON igual que XML és un llenguatge de representació de dades en mode text, però amb la diferencia que JSON no conté informació sobre capçaleres i resulta un llenguatge més lleuger, característica molt interessant per a la seva transmissió més efectiva per la xarxa, entre dispositius.

Exemple en XML:

<estudiants>
    <estudiant>
        <nom>David</nom> <cognom1>Vidal</cognom1> <cognom2>Soler</cognom2>
    </estudiant>
    <estudiant>
        <nom>Roser</nom> <cognom1>Puig</cognom1> <cognom2>Ferrer</cognom2>
    </estudiant>
    <estudiant>
        <nom>Pere</nom> <cognom1>Serra</cognom1> <cognom2>Martí</cognom2>
    </estudiant>
</estudiants>

Sintaxi JSON

La sintaxi JSON és una sintaxi similar a Javascript, ja que aquest model de representació en prové directament.

La sintaxi JSON deriva de la sintaxi de notació JavaScript:

- Les dades són parells nom/valor
- Les dades es separen per comes
- Els objectes estan envoltats dels símbols { }
- Els arrays estan envoltats dels símbols [ ]

Exemple nom/valor:

"cognom" : "Puig"

Els valors en JSON poden ser:

- Un numero (enter o coma flotant)
- Una cadena de caràcters (entre símbols " " )
- Un booleà (true o false)
- Un array (entre els símbols [ ] )
- Un objecte (entre símbols { } )
- O null

Exemple objecte:

{"nom": "David","cognom1": "Vidal","cognom2": "Soler"}


Exemple array:

"estudiants":[
    {"nom":"David", "cognom1":"Vidal", "cognom2":"Soler"},
    {"nom":"Roser", "cognom1":"Puig", "cognom2":"Ferrer"},
    {"nom":"Pere", "cognom1":"Serra", "cognom2":"Martí"}
]

JSON en Javascript/HTML

Podrem emprar les funcions nadives de Javascript per tractar cadenes de caràters en format JSON, tal i com es mostra en el següent exemple:

<!DOCTYPE html>
<html>
   <body>
      <h2>JSON en Javascript/HTML</h2>
      <p id="demo"></p>
      <script>
         var text = '{"nom":"David","cognom1":"Vidal","cognom2":"soler"}';

         var obj = JSON.parse(text);

         document.getElementById("demo").innerHTML =
            obj.nom + "<br>" +
            obj.cognom1 + "<br>" +
            obj.cognom2;
      </script>
   </body>
</html>

Controlar ons-page

Amb Angular podem establir funcions de control sobre diferents apartats de la nostra interficie Onsen. Per fer-ho cal que emmagatzemem la inicialització de onsen en una variable tal i com es mostra a continuació.

var module = ons.bootstrap('my-app', ['onsen']);

Els controladors cal que els creem de la forma següent:

module.controller('MyAppController', function($scope) {

   ons.ready(function() {
      // Init code here
      console.log("preparat");
   });
});

El nom del controlador és lliure i serà el que associarem posteriorment a la etiqueta Onsen de la interficie. Com a nexe d'unió de les dades emprem un espai anomenat $scope que s'encarrega d'emmagatzemar tota aquella informació que posteriorment es vulgui fer servir des de la interficie.

La funció definida ons.ready és la funció equivalent i que també recull el event deviceready per tant en cas d'emprar onsen conjuntament amb cordova podrem fer servir aquesta funció.

Per associar TOTA l'aplicació a un controlador cal que ho indiquem en la etiqueta html, tal i com es mostra a continuació.

<html ng-controller="MyAppController">

Cada controlador abarca allò que abarca la etiqueta a la qual està associada, en aquest cas,  es tractaria d'un controlador que treballaria amb totes les etiquetes, encara que el més habitual seria establir un controlador per cada pagina.

<ons-page ng-controller="indexPageController">

I creariem un controlador com segueix a continuació

module.controller('indexPageController', function($scope) {
   $scope.missatge="Hola classe";
});

Tal i com hem comentat anteriorment podem emprar $scope per passar informació des de codi Javascript/Angular a la vista. En aquest cas passem una variable anomenada missatge que contindrà una cadena de caracters. Per fer-ho servir en la vista serà necessari incloure-ho dins l'ambit d'actuació del controlador. Inclouriem les linies següents en el body.

<ons-navigator title="Navigator" var="myNavigator">
         <ons-page ng-controller="indexPageController">
            <ons-toolbar>
               <div class="center">APP Controlada</div>
            </ons-toolbar>
            <div>
               <p>{{missatge}}</p>
            </div>
         </ons-page>
      </ons-navigator>

Crear funcions dins controlador

En determinades ocasions ens serà necessari aïllar codi dins d'un controlador, en les condicions tradicionals ho fariem en una funció, en Angular també però declarant la funció com si es tractes d'una variable.

var fnHolaMon = function () {
   alert("hola món");
};

Aquesta funció només seria accessible des del propi controlador i mai des de la interficie. En cas que volguessim compartir aquesta funció amb la interficie caldria definir la funció com una variable del $scope, tal com es mostra a continuació.

   $scope.fnHolaMon=function (){
      alert("hola món");
   };

Repetir etiquetes via JSON

AngularJS permet repetir QUALSEVOL etiqueta simplement afegint l'atribut ng-repeat.

Per exemple, tindriem un controlador com el que segueix a continuació:

var module = ons.bootstrap('my-app', ['onsen']);

module.controller('MyAppController', function($scope) {

   ons.ready(function() {
      // Init code here
      console.log("preparat");
   });
});

module.controller('indexPageController', function($scope) {

   $scope.missatge="Centres Lleida";

   $scope.dades_json= [
      {
         centre: "Institut Almata",
         local: "Balaguer",
         cfgs: [
            {
               nom: "Desenvolupament d'aplicacions multiplataforma",
            },
            {
               nom: "Desenvolupament d'aplicacions Web",
            }
         ],
      },
      /********************* NOU REGISTRE *****************************/
      {
         centre: "Institut Caparrella",
         local: "Lleida",
         cfgm: [
             { nom: "Electromecanica vehicles", }
         ],
         cfgs:[
            { nom: "Sistemes de telecomunicacions i informàtics", },
            { nom: "Automoció", },
            { nom: "Desenvolupament d'aplicacions web", }
         ],

      },
   ];

});

I en la vista tindriem el següent:

<html ng-controller="MyAppController">
   <head>

      <meta name="format-detection" content="telephone=no">
      <meta name="msapplication-tap-highlight" content="no">
      <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">


      <link rel="stylesheet" href="lib/onsen/css/onsenui.css"/>
      <link rel="stylesheet" href="lib/onsen/css/onsen-css-components-sunshine-theme.css"/>

      <script src="lib/onsen/js/angular/angular.js"></script>
      <script src="lib/onsen/js/onsenui.js"></script>

      <!--      <script type="text/javascript" src="cordova.js"></script>-->
      <script type="text/javascript" src="js/index.js"></script>

      <title>Hello World</title>

   </head>
   <body>

      <ons-navigator title="Navigator" var="myNavigator">
         <ons-page ng-controller="indexPageController">
            <ons-toolbar>
               <div class="center">APP Repeat</div>
            </ons-toolbar>
            <div>
               <h3>{{missatge}}</h3>
               <ul>
                  <li ng-repeat="ins in dades_json">{{ins.centre}}</li>
               </ul>
            </div>
         </ons-page>
      </ons-navigator>

   </body>
</html>

Si executessim aquesta pàgina obtindriem la següent aplicació.

Filtrar en un repeat

AngularJS ens permet aplicar filtres, ordenacions i altres operacions a tots els elements d'un Array com l'obtingut anteriorment amb JSON.Anem a veure com podrem filtrar automaticament el llistat anterior de centres associant-ho a una casella de text.

Per fer-ho, primer cal crear l'element de formulari que s'encarregarà d'establir els paràmetres de la cerca, en aquest cas serà un input text.

Cercar: <input type="text" ng-model="cercador"/>

Unicament caldrà associar-hi una variable AngularJS a l'atribut ng-model, en aquest cas li direm cercador.

Despres serà necessari associar la repetició i advertir AngularJS que ha de filtrar tot el contingut segons els criteris establerts en el input text.

<li ng-repeat="ins in dades_json | filter:cercador">{{ins.centre}}</li>

Amb aquest criteri utilitza tot allò que l'usuari introdueixi en el cercador per buscar coincidència en qualsevol camp del JSON, si per exemple introduiu la lletra C, ins almatà continua apareixent tot i no tenir cap C en el nom, però com que en la resta de camps, apareix la lletra C, aquest centre continua apareixent.

Per fixar una cerca a un camp concret hauriem de modificar el filtre com es detalla a continuació.

 <li ng-repeat="ins in dades_json | filter:{centre:cercador}">{{ins.centre}}</li>

Altres operacions: ng-show / ng-hide / orderBy ..

      <ons-navigator title="Navigator" var="myNavigator">
         <ons-page ng-controller="indexPageController">
            <ons-toolbar>
               <div class="center">APP Repeat</div>
            </ons-toolbar>
            <div>
               <h3>{{missatge}}</h3>

               Cercar: <input type="text" ng-model="cercador"/>

               <ul>
                  <li ng-repeat="ins in dades_json | orderBy:['local','centre'] | filter:{centre:cercador} ">{{ins.centre}} es troba a {{ins.local}}
                     <ul>
                        <li ng-show="ins.cfgm.length<1 || ins.cfgm==null ">No hi ha Cicles GM</li>
                        <li ng-repeat="gm in ins.cfgm">CFGM {{gm.nom}}</li>
                        <li ng-repeat="gs in ins.cfgs">CFGS {{gs.nom}}</li>
                     </ul>
                  </li>
               </ul>
            </div>
         </ons-page>
      </ons-navigator>

Obtenir dades servidor REST

En el següent exemple, teniu una APP que permet crear i mostrar noticies que estan emmagatzemades en un servidor i respon a peticions REST (GET, POST, DELETE)

Arxius:

- index.html que conté la pagina principal
- news_create.html que conté el formulari d'entrada de noticies noves
- main.hs que conté la logica i les crides a servidor

[ PROJECTE ]

Exercici

Es demana que desenvolupeu una aplicació com la següent:

Les noticies només contenen tres camps: data, titular i text. Intenteu configurar l'aplicació per a que mostri també la pantalla de creació de noves noticies.