Som vi har sett i tidligere leksjoner, er utformingen av en visning for en ViewModel som å lage en HTML-mal for en JavaScript-objekt. En integrert del av ethvert templeringssystem er evnen til å kontrollere strømmen av utførelsen av mal. Muligheten til å løpe gjennom datalister og inkludere eller ekskludere visuelle elementer basert på visse forhold gjør det mulig å minimere markering og gir deg full kontroll over hvordan dataene dine vises.
Vi har allerede sett hvordan for hver
bindende kan sløyfe gjennom et observerbart array, men Knockout.js inneholder også to logiske bindinger: hvis
og hvis ikke. I tillegg gjør det med binding at du manuelt kan endre omfanget av malblokker.
Denne leksjonen introduserer Knockout.js 'kontroll-flyt-bindinger ved å utvide handlekurven eksempelet fra forrige leksjon. Vi vil også utforske noen av nyansene av for hver
som ble glanset over i den siste leksjonen.
for hver
bindingLa oss begynne med å se nærmere på vårt eksisterende for hver
løkke:
Når Knockout.js møter for hver
i data-bind
attributt, det iterates gjennom shoppingCart array og bruker hvert element den finner for bindende sammenheng av det inneholdte oppslaget. Denne bindende konteksten er hvordan Knockout.js styrer omfanget av looper. I dette tilfellet er det derfor vi kan bruke navn og prisegenskaper uten å referere til en forekomst av Produkt.
Bruk av hvert element i en matrise som den nye bindende konteksten er en enkel måte å lage sløyfer på, men denne oppførselen gjør det også umulig å referere til objekter utenfor gjeldende element i iterasjonen. Av denne grunn gjør Knockout.js flere spesielle egenskaper tilgjengelig i hver bindende sammenheng. Merk at alle disse egenskapene kun er tilgjengelige i utsikt, ikke ViewModel.
$ root
EiendomDe $ root
kontekst refererer alltid til ViewModel på toppnivå, uavhengig av looper eller andre endringer i omfang. Som vi så i forrige leksjon, gjør dette det mulig å få tilgang til toppnivå metoder for å manipulere ViewModel.
$ data
EiendomDe $ data
Egenskapen i en bindende sammenheng refererer til ViewModel-objektet for gjeldende kontekst. Det er mye som dette
søkeord i et JavaScript-objekt. For eksempel, innenfor vår forkant: shoppingCart-sløyfe, refererer $ data til gjeldende listepost. Som et resultat fungerer følgende kode akkurat som den ville uten å bruke $ data:
Dette kan virke som en triviell eiendom, men det er uunnværlig når du er iterating gjennom arrays som inneholder atomverdier som strenger eller tall. For eksempel kan vi lagre en liste over strenger som representerer koder for hvert produkt:
funksjon Produkt (navn, pris, koder) this.name = ko.observable (navn); this.price = ko.observable (pris); tags = typeof (tags)! == 'undefined'? koder: []; this.tags = ko.observableArray (tags);
Deretter definerer du noen koder for en av produktene i handlevogn
matrise:
nytt produkt ("Boller", 1,49, ['Bakt varer', 'Hotdogs']);
Nå kan vi se $ data konteksten i aksjon. I
element som inneholder a
tags matrise: |
Innsiden av foreach: tags
loop, Knockout.js bruker de innfødte strengene "Bakt varer" og "Pølser" som bindende sammenheng. Men siden vi ønsker å få tilgang til de faktiske strengene i stedet for deres eiendommer, Vi trenger $ dataobjektet.
$ index
EiendomInnsiden av a for hver
loop, den $ index
Egenskapen inneholder indeksens nåværende element i arrayet. Som de fleste ting i Knockout.js, oppdateres verdien av $ indeks automatisk når du legger til eller sletter et element fra det tilknyttede observable arrayet. Dette er en nyttig egenskap hvis du trenger å vise indeksen for hvert element, slik som:
$ forelder
EiendomDe $ forelder
eiendom refererer til det overordnede ViewModel-objektet. Vanligvis trenger du bare dette når du jobber med nestede løkker, og du må få tilgang til egenskaper i den ytre sløyfen. For eksempel, hvis du trenger tilgang til Produkt
forekomst fra innsiden av foreak: taggsløyfe, du kan bruke $ foreldreegenskapen:
Mellom observerbare arrays, den for hver
bindende og bindende kontekstegenskaper diskutert tidligere, bør du ha alle verktøyene du trenger for å utnytte arrayer i dine Knockout.js webprogrammer.
Før vi går videre til betingede bindinger, skal vi legge til en rabatt
eiendom til vår produkt klasse:
funksjon Produkt (navn, pris, koder, rabatt) ... discount = typeof (rabatt)! == 'undefined'? rabatt: 0; this.discount = ko.observable (rabatt); this.formattedDiscount = ko.computed (function () return (this.discount () * 100) + "%";, dette);
Dette gir oss en tilstand vi kan sjekke med Knockout.js logiske bindinger. Først gjør vi rabatt
parameter valgfri, og gir den en standardverdi på 0. Deretter oppretter vi en observerbar for rabatten, så Knockout.js kan følge endringene. Endelig definerer vi en beregningsbar observerbar som gir en brukervennlig versjon av rabattprosenten.
La oss gå videre og legge til 20% rabatt på den første varen i PersonViewModel.shoppingCart
:
this.shoppingCart = ko.observableArray ([nytt produkt ("Bier", 10.99, null, .20), nytt produkt ("Brats", 7.99), nytt produkt ("Boller", 1,49, ['Bakt varer' Pølser']); ]);
hvis og hvis ikke
BindingerDe hvis
bindende er en betinget binding. Hvis parameteren du passerer evaluerer til sann, vil den innebygde HTML bli vist, ellers blir den fjernet fra DOM. For eksempel, prøv å legge til følgende celle i
Du lagret !!! | elementet vil bare vises for varer som har en rabatt større enn 0 . I tillegg, siden rabatt er en observerbar, vil Knockout.js automatisk revurdere tilstanden når den endres. Dette er bare en annen måte. Knockout.js hjelper deg med å fokusere på dataene som kjører programmet. Figur 15: Tilbyr betinget av rabatt for hvert produkt Du kan bruke noen JavaScript-uttrykk som betingelse: Knockout.js vil prøve å evaluere strengen som JavaScript-kode og bruke resultatet til å vise eller skjule elementet. Som du kanskje har gjettet, De |