I den siste artikkelen introduserte jeg deg til NativeScript. Der lærte du grunnleggende om NativeScript og hvordan det skiller seg fra andre mobile utviklingsrammer. Denne gangen får du hendene dine skitne ved å lage din første NativeScript-app. Jeg vil gå gjennom hele prosessen med å bygge en app med NativeScript, fra å sette opp utviklingsmiljøet til å kjøre appen på enheten din. Her er en oversikt over hva jeg skal diskutere:
Vi kjører spesifikt appen på Android-plattformen. Men du kan fortsatt følge med hvis du vil distribuere til iOS, da koden vil være stort sett den samme. De eneste forskjellene er i ferd med å sette opp NativeScript og kommandoene du kjører når du kjører appen.
Den fullførte kildekoden for denne appen er tilgjengelig fra opplæringen GitHub repo.
For å konfigurere NativeScript må du først installere Node.js. Når Node.js er installert, kan du installere NativeScript kommandolinjeverktøyet ved å kjøre npm installere -g nativescript
på terminalen din.
Det siste trinnet er å installere utviklingsverktøyet for hver plattform du vil distribuere til. For Android er dette Android SDK. For iOS er det XCode. Du kan følge installasjonsveiledningen på NativeScript-nettstedet for mer detaljerte instruksjoner om hvordan du konfigurerer nødvendig programvare for utviklingsmiljøet.
Når du har satt opp miljøet, utfør tns lege
for å sikre at miljøet ditt er klart for NativeScript-utvikling. Hvis du er på Linux eller Windows, ser du noe slikt hvis miljøet ditt er klart:
MERK: Du kan bare utvikle for iOS på Mac OS X-systemer. For å kunne arbeide med iOS-enheter og -prosjekter, trenger du Mac OS X Mavericks eller senere. Dine komponenter er oppdaterte. Ingen problemer ble oppdaget.
Det er et notat der du bare kan utvikle for iOS på Mac OS X-systemer. Dette betyr at hvis du er på en PC, kan du bare distribuere til Android-enheter. Men hvis du er på Mac, kan du distribuere på både iOS og Android-plattformer.
Hvis du får problemer med oppsettet, kan du få en invitasjon til å delta i NativeScript Slack Community, og når du har blitt med, kan du gå til startkanalen og stille dine spørsmål der inne.
Appen som vi skal bygge er en notatopptak. Det vil tillate brukeren å lage notater, hver med et valgfritt bildevedlegg som vil bli tatt med enhetskameraet. Notatene vedvarer ved hjelp av NativeScript-programinnstillinger, og kan slettes individuelt.
Slik ser appen ut:
Begynn med å utføre følgende kommando for å opprette et nytt NativeScript-prosjekt:
tns opprette noter --appid "com.yourname.noter"
noter
er navnet på prosjektet, og com.yourname.noter
er den unike app-IDen. Dette vil bli brukt senere til å identifisere appen din når du har sendt den til Play eller App Store. Som standard er tns opprette
kommandoen vil opprette følgende mapper og filer for deg:
Du trenger vanligvis bare å berøre filene inni app katalogen. Men det er også tilfeller der du kanskje må redigere filer inni plattformer /android katalogen. Et slikt tilfelle er når et plugin du prøver å bruke, forbinder ikke automatisk avhengighetene og eiendelene det trenger.
Deretter navigerer du til app kataloger og slett alle filer bortsett fra App_Resources mappe. Deretter oppretter du følgende filer:
Dette er filene som vil bli brukt av NativeScript runtime. Akkurat som når du bygger websider, .css filer brukes til styling, og .js filer for funksjonalitet. Men for oppretting av appen bruker vi XML istedenfor HTML. Vanligvis vil du opprette en egen mappe for hvert skjermbilde av appen (for eksempel logg inn, registrer deg eller dashbord) og ha XML-, CSS- og JavaScript-filer i hver mappe. Men siden denne appen har bare en skjerm, opprettet vi alle filene i rotkatalogen.
Hvis du trenger mer informasjon om NativeScript-katalogstrukturen, kan du se kapittel 2 i NativeScript Komme i gang-veiledningen.
Åpne app.js fil og legg til følgende kode:
var søknad = krever ("søknad"); application.start (modulnavn: "notater-side");
Dette er inngangspunktet for et NativeScript-program. Den bruker applikasjonsmodulen og dens start
Metode for å spesifisere modulen som brukes til den første siden av appen. I dette tilfellet har vi spesifisert notater-side
, som betyr at modulen er notater-page.js, markeringen er notater-page.xml, og stylingen til siden er notater-page.css. Dette er en konvensjon som brukes i NativeScript, at alle filer for en bestemt side må ha samme navn.
Åpne notater-page.xml fil og legg til følgende kode:
Når du lager app-sider i NativeScript, bør du alltid begynne med
stikkord. Slik vet du at NativeScript prøver å lage en ny side. De xmlns
Attributt spesifiserer nettadressen til skjemaet som brukes for XML-filen.
Hvis du besøker skjemaadressen som er oppgitt, kan du se definisjonen av alle XML-kodene som du kan bruke i NativeScript. De lastet
Attributt angir funksjonen som skal utføres når siden er lastet. Vi tar en titt på denne funksjonen definisjonen senere i notater-page.js fil.
...
Som standard inneholder appoverskriften tittelen på appen. Hvis du vil legge til andre UI-komponenter, må du omdefinere den ved å bruke
. Deretter definerer du inni tingene de tingene du vil se i overskriften. Tittelen er spesifisert ved bruk av
og sette sin tittel
Tilordne sidetittelen du vil ha.
Nedenfor har vi brukt overskriften syntaks til å utføre verdien av APP_TITLE
definert i notater-page.js fil. Slik utfører du verdier som er bundet til siden.
...
For å definere knapper, bruk først
som foreldre, og hver
vil være knappene du vil definere. De springen
Attributt angir en funksjon som skal utføres når knappen tappes, mens os.position
og android.position
er posisjonene til knappen i iOS og Android.
For å angi knappeteksten, kan du bruke
's tekst
Egenskap. Imidlertid tillater NativeScript for øyeblikket ikke å endre tekstfargen på knappen gjennom CSS. Derfor har vi brukt i stedet
å definere innholdet på knappen og for å angi tekstfarge.
Neste er det faktiske sidens innhold. Du kan ordne de forskjellige elementene ved å bruke en eller flere av oppsettbeholderne. Nedenfor har vi brukt to av de tilgjengelige layoutene: StackLayout
og Gridlayout
.
StackLayout
lar deg stable alle elementene inne i den. Som standard er orienteringen til dette oppsettet vertikalt, slik at hver brukergrensesnittkomponent er stablet under det siste. Tenk på lego murstein med en nedadgående strømning.
På den andre siden, Gridlayout
lar deg ordne elementer i en bordstruktur. Hvis du noen gang har brukt Bootstrap eller andre CSS grid rammer, bør dette virke naturlig for deg. De Gridlayout
Lar deg definere rader og kolonner der hver UI-komponent kan plasseres. Vi tar en titt på hvordan dette implementeres senere. For nå, la oss gå videre til koden.
Først, la oss definere skjemaet for å lage et nytt notat. Akkurat som i HTML, kan du definere attributter som id
og cssClass
(tilsvarende HTML-er klasse
Egenskap). De id
Attributtet er knyttet til et element hvis du vil manipulere det fra kode. I vårt tilfelle ønsker vi å animere skjemaet senere. cssClass
brukes til å spesifisere CSS-klassen du vil bruke til å stile elementet.
Inne i skjemaet er et tekstfelt for å legge inn notat tittelen, en knapp for å legge ved et bilde, det valgte bildet og en knapp for å lagre notatet. Bildelementet er kun synlig hvis attachment_img
har en truthy verdi. Det vil være tilfelle hvis et bilde tidligere var vedlagt.
Neste er listen som viser notatene som allerede ble lagt til av brukeren. Lister opprettes ved å bruke Listevisning
komponent. Dette aksepterer elementer
som en nødvendig attributt. Verdien kan enten være en vanlig tabell eller en observerbar rekkefølge.
Hvis du ikke trenger å utføre noen form for oppdatering (for eksempel å slette eller oppdatere et felt) til hvert element i arrayet, vil et vanlig JavaScript-array gjøre. Ellers kan du bruke en observerbar rekkefølge som lar deg utføre oppdateringer til arrayet og få den automatisk reflektert til brukergrensesnittet. Vi tar en titt på hvordan et observerbart array er definert senere.
Vær også oppmerksom på at a Listevisning
kan ha en itemTap
attributt, som lar deg spesifisere funksjonen som skal utføres når et element i Listevisning
er tappet. Men i dette tilfellet har vi ikke lagt til det siden vi ikke trenger å utføre noen handling når et element er tappet.
...
Elementene i Listevisning
kan defineres ved hjelp av
. Her bruker vi en
å lage to rader og to kolonner. De kolonner
Attributt brukes til å angi hvor mange kolonner du vil ha i hver rad.
I dette tilfellet, *, *
betyr at det er to kolonner som hver tar opp samme mengde ledig plass i den nåværende raden. Så hvis hele raden har en total bredde på 300 piksler, vil hver kolonne være 150 piksler bred. Så i utgangspunktet hver *
representerer en kolonne, og du bruker et komma for å skille hver av dem.
De rader
Attributtet fungerer på samme måte, men kontrollerer hvor mye plass som brukes av en enkelt rad. auto
betyr at det bare vil forbruke den plassen som trengs for barna av hver rad.
Etter å ha definert kolonner
og rader
i Gridlayout
, du må fortsatt spesifisere hvilken av barna som tilhører hvilken rad og kolonne. Den første raden inneholder tittel på elementet (1. kolonne) og slettknappen (2. kolonne). Den andre raden inneholder bildet som ble festet til elementet (1. kolonne). Raden og kolonnene er spesifisert ved å bruke rad
og col
attributt for hvert element.
Legg merke til bruken av horizontalAlignment
og vertikal justering
. Du kan tenke på dette som NativeScript-ekvivalent av HTML-er tekst-Juster
Egenskap. Men i stedet for tekst, tilpasser vi UI-komponenter. horizontalAlignment
kan ha en verdi på Ikke sant
, venstre
, senter
, eller tøye ut
, samtidig som vertikal justering
kan ha en verdi på topp
, bunn
, senter
, eller tøye ut
. De fleste av disse er selvforklarende, bortsett fra tøye ut
, som strekker seg for å ta opp tilgjengelig horisontal eller vertikal plass.
I dette tilfellet, horizontalAlignment
og vertikal justering
brukes til å sentrere bildet både horisontalt og vertikalt inne i kolonnen. Og horizontalAlignment
brukes på sletteknappen for å justere den til høyesteparten av den andre kolonnen.
Vi har ikke spesifisert en itemTap
attributt for Listevisning
. I stedet vil vi legge ved en slettingshandling som vil bli utført når en sletteknapp inne i et listeelement tappes. Hvert element har en index
attributt, som vi overfører som et egendefinert attributt for sletteknappen. Dette er den unike nøkkelen som brukes til å identifisere hvert element slik at vi enkelt kan referere til dem når det er nødvendig.
Legg også merke til lastet
Egenskap. Akkurat som
har en lastet
attributt, knapper kan også ha en. Du vil se senere hvordan dette brukes.
Nå er vi klare til å se på JavaScript som gjør at alt fungerer. I denne delen kodes vi for notater-page.js fil.
Først importerer vi data / observerbar
og data / observerbar-matrise
moduler. Disse er innebygde moduler i NativeScript som lar oss lage observerbare objekter og arrayer. Observables lar oss automatisk oppdatere brukergrensesnittet når disse objekter og arrayer blir oppdatert.
I vår app, pageArray
brukes til å lagre rekke notater, og pageData
brukes til å knytte den til siden. pageData
Fungerer også som den generelle beholderen for alle dataene vi vil vise i brukergrensesnittet.
var Observerbar = krever ("data / observerbar"); var ObserverbarArray = krever ("data / observerbar array"); var pageArray = new ObservableArray.ObservableArray (); var pageData = new Observable.Observable (notater: pageArray);
Deretter importerer du alle de andre modulene som vi skal bruke på denne siden:
kamera
: for å arbeide med enhetskameraet.utsikt
: for å referere til bestemte elementer på siden. Tenk på det som ekvivalent av document.getElementById
i NativeScript.UI / enums
: en global ordbok med konstante verdier for alt relatert til grensesnitt.ui / animasjon
: for animerende elementer.applikasjon innstillinger
: for vedvarende lokale data.filsystem
: for å arbeide med filsystemet.var cameraModule = krever ("kamera"); var view = krever ("ui / core / view"); var uiEnums = krever ("ui / enums"); var animasjon = krever ("ui / animasjon"); var appSettings = krever ("programinnstillinger"); var fs = krever ("filsystem");
Deretter initialiserer du verdiene for variablene som skal brukes i hele filen. side
brukes til å lagre en referanse til gjeldende side, notesArr
er vanlig array kopi av nåværende notater på siden, og CURRENT_INDEX
er den opprinnelige verdien til indeksen som brukes som den unike ID for hver notat.
var side; var notesArr = []; var current_index = -1;
pageLoaded ()
FunksjonFunksjoner blir tilgjengelige i sammenheng med siden ved hjelp av eksport
. Tidligere i notater-page.xml fil, så du at pageLoaded ()
funksjonen utføres når siden er lastet inn.
exports.pageLoaded = funksjon (args) ...
Inne i pageLoaded ()
funksjon, begynner vi å få referansen til siden. Deretter viser vi skjemaet for å lage et nytt notat, og få de lagrede verdiene for den nye notat tittelen og notatene fra programinnstillingene.
side = args.object; pageData.set ('showForm', true); var new_note_title = appSettings.getString ('new_note_title'); var notater = appSettings.getString ('notater');
Neste, fortsatt innenfor pageLoaded ()
funksjon, sjekk om det finnes notater som er lagret lokalt. Hvis ikke, oppretter vi en rekke notater. Dette oppsettet vil tjene som standardinnhold for nye brukere av appen. Men hvis det allerede er lagret noen notater lokalt, konverterer vi dem til en matrise og deretter skyver du dataene til det observerbare arrayet.
Vær oppmerksom på at før vi skyver elementene i det observerbare systemet, kontrollerer vi først om det er tomt. Vi må gjøre dette fordi du bruker kameramodulen til å utføre lastet
hendelse på siden igjen etter at et bilde er valgt. Dette betyr at hvis vi ikke er forsiktige, vil vi ende opp med å skyve duplikater inn i matrisen hver gang brukeren bruker kameraet.
hvis (! notater) notater = [indeks: 0, tittel: '100 push ups', indeks: 1, tittel: '100 sit ups', indeks: 2, tittel: '100 squats', indeks: 3, tittel: '10km kjører']; ellers notater = JSON.parse (notater); notaterArr = notater; hvis (! pageArray.length) for (var x = 0; x < notes.length; x++) current_index += 1; pageArray.push(notes[x]);
Nå som vi har notatdataene opprettet, kan vi oppdatere sidetittelen ved å sette inn den ITEM_TITLE
Tilordne verdien vi fikk fra programinnstillingene tidligere. Deretter bindes pageData
til siden, slik at brukergrensesnittet automatisk blir oppdatert når en endring er gjort til elementene vi har satt.
pageData.set ('item_title', new_note_title); args.object.bindingContext = pageData;
Animer skjemaet for å lage nye notater. Vi gjør dette ved å bruke getViewById
fungere i utsikt
og passerer i konteksten (den nåværende siden) som det første argumentet og id
attributt tildelt elementet du vil manipulere.
Neste, ring på animere
funksjon. Dette aksepterer et objekt som inneholder animasjonsinnstillingene. Her ønsker vi at skjemaet skal skyve ned 160 piksler fra sin opprinnelige posisjon over en periode på 800 millisekunder.
view.getViewById (side, 'form'). animate (translate: x: 0, y: 160, varighet: 800,);
newNote ()
FunksjonDe newNote ()
funksjonen utføres når brukeren tapper på Ny gjenstand handlingsobjekt på toppteksten. Dette gjemmer og viser det nye elementet Listevisning
og glir skjemaet opp eller ned avhengig av gjeldende verdi av showForm
.
Hvis showForm
er ekte
, som betyr at den for øyeblikket blir vist, endrer vi opaciteten til Listevisning
til 1
i løpet av 400 millisekunder, og skyv deretter skjemaet for å skjule det. Ellers skjuler vi Listevisning
og skyv skjemaet ned.
exports.newNote = function () var showForm = pageData.get ('showForm'); var top_position = (showForm)? -160: 160; var list_visibility = (showForm)? 1: 0; view.getViewById (side, 'liste'). animate (opacity: list_visibility, duration: 400); view.getViewById (side, 'form'). animate (translate: x: 0, y: toppposisjon, varighet: 800,); pageData.set ('showForm',! showForm);
btnLoaded ()
FunksjonI notater-page.xml fil, vi har en lastet
Tilordne i knappen for å slette et notat. Dette er funksjonen som blir utført når hendelsen skjer.
Som standard er funksjonen tilordnet til itemTap
attributt i Listevisning
vil ikke bli utført når en knapp er definert i a Listevisning
punkt. Dette skyldes at NativeScript antar at handlingene som skal utføres for hvert listeelement, kun utløses fra disse knappene.
Koden nedenfor er en løsning for den vanlige oppførselen. Dette fjerner i utgangspunktet fokus på sletteknappen, slik at du fortsatt kan utføre en funksjon når en bruker tapper på en Listevisning
punkt. I dette tilfellet trenger vi ikke virkelig denne koden siden vi ikke har tildelt noen funksjonalitet til kraner, men det er et godt verktøy å ha når du arbeider med lister.
exports.btnLoaded = funksjon (args) var btn = args.object; btn.android.setFocusable (false);
åpent kamera()
FunksjonNeste er åpent kamera()
funksjon, som blir utført når brukeren tapper på Fest bilde knapp. Den nåværende tilstanden opprettholdes ikke ved bruk av kameramodulen, så vi må først lagre tittelen på det nye notatet i programinnstillingene.
Etterpå kan vi starte standard kameraprogrammet i enheten ved å ringe ta bilde()
metode. Denne metoden aksepterer et objekt som inneholder bildeinnstillingene. Når brukeren har tatt et bilde og tappet på Lagre knappen i Android eller bruk bilde knappen på iOS, løftet løser og tilbakeringingsfunksjonen overføres til deretter()
blir henrettet.
Selve bildet blir sendt som et argument til funksjonen, og vi bruker dette til å lagre filen på dokumentbanen. Når det er gjort, lagrer vi hele filbanen til appinnstillingene og den aktuelle appestaten slik at vi kan få verdien senere, før du lagrer notatet.
exports.openCamera = funksjon () appSettings.setString ('new_note_title', pageData.get ('item_title')); cameraModule.takePicture (bredde: 300, høyde: 300, keepAspectRatio: true). deretter (funksjon (img) var filepath = fs.path.join (fs.knownFolders.documents (). path, "img_" + ny dato (). getTime () / 1000) + ".jpg"); img.saveToFile (filepath, uiEnums.ImageFormat.jpeg); appSettings.setString ('new_note_photo', filepath); pageData.set ('attachment_img' filepath););
saveNote ()
FunksjonDe saveNote ()
funksjonen utføres når brukeren tapper på Lagre notat knapp. Dette får den nåværende verdien av notat tittel tekstfeltet og bildebanen, øker CURRENT_INDEX
, og skyver det nye elementet i ren sedler og observable notater. Deretter lagrer den nåværende notatene og CURRENT_INDEX
i programinnstillingene, fjerner verdiene for det nye notatet fra programinnstillingene, oppdaterer brukergrensesnittet slik at skjemaet viser sin tomme tilstand, og viser listen mens du skjuler det nye notatskjemaet.
exports.saveNote = function () var new_note_title = pageData.get ('item_title'); var new_note_photo = pageData.get ('attachment_img'); current_index + = 1; var new_index = current_index; var new_item = indeks: new_index, tittel: new_note_title, foto: new_note_photo, show_photo: false; notesArr.push (NEW_ITEM); pageArray.push (NEW_ITEM); appSettings.setString ('notater', JSON.stringify (notesArr)); appSettings.setNumber ('current_index', new_index); appSettings.remove ( 'new_note_title'); appSettings.remove ( 'new_note_photo'); pageData.set ('showForm', false); pageData.set ('item_title', '); pageData.set (' attachment_img ', null); view.getViewById (side,' liste '). animate (opacity: 1, duration: 400); view.getViewById side, 'form'). animate (translate: x: 0, y: -160, varighet: 800,);
deleteNote ()
FunksjonTil slutt har vi deleteNote ()
funksjon som blir utført når en bruker tapper på sletteknappen inne i en liste element. Som du allerede har sett fra tidligere funksjoner, sendes en gjenstand som et argument til funksjoner som er vedlagt som en hendelsesbehandler for en bestemt komponent. Dette objektet har gjenstand
eiendom, som refererer til selve komponenten.
Derfra kan du få verdien av et attributt som ble sendt til det. I dette tilfellet får vi verdien av index
attributt, og vi bruker det for å få den faktiske indeksen for elementet som vi vil slette.
exports.deleteNote = funksjon (args) var target = args.object; var index_to_delete = notesArr.map (funksjon (e) return e.index;). indexOf (target.index); notesArr.map (funksjon (element, indeks) if (index == index_to_delete) notesArr.splice (index_to_delete, 1); pageArray.splice (index_to_delete, 1); return false;); appSettings.setString ('notater', JSON.stringify (notesArr));
Åpne app.css fil og legg til følgende globale stiler:
ActionBar bakgrunnsfarge: # b898ff; farge: #fff; .header-item text-transform: store bokstaver; .item polstring: 20; skriftstørrelse: 20px; .form-container bakgrunnsfarge: #fff; margin-topp: -160px; polstring: 20px; z-indeks: 10; .label font-size: 18px; .link text-align: left; bakgrunnsfarge: gjennomsiktig; farge: # 0275d8; polstring: 5px; margin: 10px 0; tekst-transformer: store bokstaver; skriftstørrelse: 15px; .image width: 300; margin: 20 0; .primary-button padding: 5px; farge: #fff; bakgrunnsfarge: # 0723bb; tekst-transformer: store bokstaver; .delete-button font-size: 15px; bakgrunnsfarge: # f50029; farge: #fff;
Hvis du vil bruke sidespesifikke stiler, kan du også opprette en notater-page.css fil og definer stilene dine der inne.
Du kan kjøre appen på enheten din ved å kjøre tns kjøre
og deretter plattformen hvor du vil distribuere. Her er et eksempel på android:
tns kjøre android
Dette installerer automatisk Android-plattformen for deg hvis den ikke allerede er installert og kjører appen på enheten din når den er installert. Når appen kjører, kan du kjøre tns livesync android - watch
å automatisk oppdatere appen hver gang du gjør endringer i kildefilene.
På samme måte som alle andre apprammer, tillater NativeScript utviklere å feilsøke appen deres. Dette gjøres med Chrome Dev-verktøyene. Det er to måter å gjøre dette på:
tns debug android - start
å knytte en debugger til den kjørende forekomsten av appen.tns debug android - debug-brk
å bygge en forekomst av appen med en debugger knyttet til den.Uansett hvilket alternativ du velger, vil dette åpne en ny fane i Google Chrome-nettleseren som gjør at du kan feilsøke appen akkurat som en vanlig JavaScript-nettapp. Dette betyr at du faktisk kan bruke console.log
i kildekoden for å inspisere innholdet i variablene du jobber med.
I denne artikkelen har du lært hvordan du bygger en app med NativeScript. Spesielt har du lært begreper som bruk av brukergrensesnittkomponenter, layouter, styling, animasjoner, bruk av kameraet og vedlikehold av applikasjonsstatus med programinnstillinger.
Nå som du har bygget din første NativeScript-app, er det nå på tide å ta dine ferdigheter enda lenger ved å sjekke ut hva du ellers kan gjøre med NativeScript og bygge flere apper med det.