Welkom bij de Een inhoudviewer bouwen met Backbone serie. In de eerste vier delen hebben we gekeken naar bijna elk belangrijk onderdeel dat wordt geleverd met de nieuwste versie van Backbone, inclusief modellen, controllers, weergaven en routers.
In dit deel van de tutorial gaan we onze applicatie koppelen aan een webserver, zodat we onze contacten in een database kunnen opslaan. We zullen niet naar LocalStorage kijken; dit is een populair middel om de gegevens die Backbone-apps gebruiken te behouden, maar het feit is dat er al een aantal uitstekende tutorials beschikbaar zijn over dit onderwerp.
We hebben een webserver en een database nodig voor dit deel van de tutorial. Ik gebruik Microsoft's VWD als een editor, die wordt geleverd met een ingebouwde webserver en werkt goed met MSSQL-server, dus dit is wat we zullen gebruiken. In feite maakt het niet echt uit met welke stapel je besluit te gaan.
Het installeren en configureren van een van deze technologieën (VWD en MSSQL-server) valt buiten het bestek van deze zelfstudie, maar het is relatief eenvoudig om te doen en er zijn veel goede gidsen die er zijn.
Na de installatie moet u een nieuwe database instellen met een tabel waarin de gegevens worden opgeslagen. De tabelkolommen moeten de verschillende eigenschappen weerspiegelen die onze modellen gebruiken, dus er moet een naamkolom zijn, een adreskolom, enz. De tabel kan worden gevuld met de voorbeeldgegevens die we tot nu toe in de serie hebben gebruikt.
Eén kolom die in onze nieuwe tabel zou moeten verschijnen, maar die we niet in onze lokale testgegevens hebben gebruikt, is een ID kaart
, die uniek moet zijn voor elke rij in de tabel. Voor het gebruiksgemak wilt u dit waarschijnlijk instellen op automatisch verhogen wanneer de gegevens aan de tabel worden toegevoegd.
Om met de server te communiceren, geeft Backbone ons de Synchroniseren
module; dit is de enige belangrijke module die we nog niet hebben gebruikt en door het te begrijpen, wordt onze kennis van de grondbeginselen van het raamwerk compleet.
Oproep aan de synchroniseren()
methode resulteert in een verzoek aan de server; standaard wordt ervan uitgegaan dat jQuery of Zepto in gebruik is en wordt het verzoek gedelegeerd aan degene die aanwezig is om daadwerkelijk uit te voeren. Het veronderstelt ook dat een REST-interface op de back-end wacht, dus maakt standaard gebruik van POST, PUT, GET, DELETE HTTP-methoden. Zoals we hebben gezien, kan Backbone worden geconfigureerd om terug te vallen op de oude GET- en POST-methoden met extra headers die de beoogde actie specificeren.
Evenals kunnen bellen synchroniseren()
direct, modellen en collecties hebben ook methoden die kunnen worden gebruikt om met de server te communiceren; modellen hebben de vernietigen()
, ophalen ()
, ontleden ()
en opslaan()
methoden en collecties hebben ophalen ()
en ontleden ()
. De vernietigen()
ophalen ()
en synchroniseren()
methoden die allemaal worden uitgesteld synchroniseren()
of het nu wordt gebruikt met modellen of collecties. De ontleden ()
methode, automatisch opgeroepen wanneer gegevens worden geretourneerd door de server, is standaard een eenvoudige no-op die alleen het antwoord van de server retourneert, maar kan worden opgeheven als we het antwoord vooraf willen verwerken voordat het wordt geconsumeerd.
De manier waarop modelgegevens worden gebootstrap in de pagina, is afhankelijk van de back-endtechnologie die wordt gebruikt.
De Backbone-documentatie voor de ophalen ()
methode (van een verzameling) geeft aan dat deze methode niet moet worden gebruikt bij het laden van de eerste pagina om de vereiste modellen bij de server aan te vragen. Vervolgens wordt in de sectie Veelgestelde vragen uitgelegd dat op een pagina de vereiste modules al beschikbaar moeten zijn voor de pagina bij het laden om het aanvankelijke AJAX-verzoek te voorkomen.
Dit is een geweldig idee en hoewel we het advies niet expliciet hoeven op te volgen, zal het onze applicatie net iets lastiger maken, en dat kan alleen maar goed zijn.
De manier waarop modelgegevens worden gebootstrap in de pagina, is afhankelijk van de back-endtechnologie die wordt gebruikt. We gebruiken .net in dit voorbeeld, dus een manier om dit te doen zou zijn om dynamisch een te maken element containing the required model data, and inject it into the page. To do this we'll need to convert our
index.html
file to index.aspx
instead (we'll also need an index.aspx.cs
code-behind or class file too). But doing this raises a new issue.
We can lift the 'Mustache-style' example straight off of the Underscore documentation page.
The problem with Underscore templates is that they use <%=
to specify placeholders in the template that are replaced with actual data when the template is consumed. This is the same syntax that ASPX pages use to run dynamic .Net code within HTML tags. The Underscore templates that we've used in this example so far prevent the ASPX page from running correctly and instead it displays a server error.
Fortunately there are several ways around this problem, the simplest way being to change the syntax used to specify the placeholders used in the templates. Underscore exposes the templateSettings
property for this very purpose, allowing us to easy specify a regular expression used to match the symbols we wish to use. We can lift the 'Mustache-style' example straight off of the Underscore documentation page in fact; at the start of our app.js
file (within the very outer function) we can just add the following code:
_.templateSettings = interpolate: /\\(.+?)\\/g ;
All this does is supply a new regular expression to the interpolate
method, which allows us to use the alternative syntax property
instead of <%= property %>
. We should also at this point go through the templates and change all of the original template tags to use the new syntax.
Although this is not something we've used in our templates so far, there are also additional symbols that Underscore can use. We can evaluate JavaScript using <%
and can escape data using <%-
. If we wish to use these in our templates and have replaced the interpolate
property, we should also configure the evaluate
and escape
Underscore properties as well.
We can now think about delivering the model data that is stored in a database to our page when the page is initially rendered. We can easily do this be adding a simple method to the class file for our ASPX page that reads the records from the database and creates a list of objects where each object represents a single contact. We can then serialise the list into a JavaScript array and inject it into the page. As long as the array has the same format as the dummy array we used in the first four parts of this tutorial, we won't have to change our front-end code.
As a placeholder for the array, we can just add a new element to the body of the page, directly before the reference to
app.js
, which calls the method in the code-behind:
De daadwerkelijke logica in de code achter de database die de seriële en leesbaarheidsdatabase uitvoert, kan enorm variëren, afhankelijk van de implementatie, en is enigszins buiten het bestek van deze zelfstudie - we zijn meer geïnteresseerd in het verkrijgen van die eerste payload op de pagina dan we zijn over hoe we het daadwerkelijk krijgen. Bekijk het klassenbestand in de bijbehorende codedownload voor waarschijnlijk de snelste en gemakkelijkste, maar zeker niet de beste manier om het te doen.
Op dit punt zouden we in staat moeten zijn om de matrix met contactpersonen te verwijderen waar onze dummy-gegevens vandaan kwamen app.js
, voer de pagina uit (via de ingebouwde WVD-webserver of IIS) en zie exact dezelfde pagina, met bijna dezelfde functionaliteit, zoals we aan het einde van deel 4 zagen. Yay!
In dit voorbeeld heb ik een .net 4.0 ASMX-bestand gebruikt om de aanvragen van de front-end af te handelen. Om ervoor te zorgen dat de back-end de verzonden gegevens ziet, moeten we het configureren emulateHTTP
en emulateJSON
Backbone-eigenschappen. Voeg de volgende regels rechtstreeks toe nadat we de syntaxis van de Underscore-sjabloon hebben gewijzigd:
Backbone.emulateHTTP = true; Backbone.emulateJSON = true;
Of u deze eigenschappen moet configureren wanneer u een backbone-app real-time bouwt, hangt volledig af van de back-endtechnologie waarmee u werkt.
Dus onze applicatie kan de gegevens op verschillende manieren wijzigen; het kan de kenmerken van een reeds bestaande contactpersoon wijzigen, een geheel nieuwe contactpersoon toevoegen of een bestaande contactpersoon verwijderen.
De logica om al deze dingen aan de voorkant te doen bestaat al, maar nu er een server bij betrokken is, is het gedrag van de pagina al veranderd. Hoewel de pagina wordt weergegeven zoals voorheen, proberen we een contact te verwijderen als Backbone een fout meldt met de melding dat er geen url is gedefinieerd. De reden hiervoor is omdat we de vernietigen()
methode in de Verwijder contact()
methode van onze ContactView
klasse.
Laten we eens kijken hoe u de verwijderfunctie kunt herstellen. Het eerste wat we dan moeten doen, is definiëren a url
kenmerk voor onze modellen. Voeg de eigenschap toe aan de Contact
klasse die een individueel model definieert:
url: function () return "/ContactManager.asmx/ManageContact?id=" + this.get ("id");
We specificeren een functie als de waarde van de url
eigenschap, die de URL retourneert die moet worden gebruikt om de aanvragen te maken. In dit voorbeeld kunnen we een asmx-webservicebestand gebruiken om de aanvragen af te handelen. We voegen ook de naam van onze webmethode toe (ManageContact
) en voeg het toe ID kaart
van het model als een queryreeksparameter.
Als we nu een van de contactpersonen verwijderen wanneer we de pagina uitvoeren, wordt er een POST-aanvraag naar de webservice gedaan. Een X-HTTP-methode-Override
header wordt toegevoegd aan de aanvraag die aangeeft dat de beoogde HTTP-methode was DELETE
. We kunnen dit in onze webservicelogica gebruiken om te bepalen welke actie moet worden ondernomen in de database.
Vervolgens kunnen we het saveEdits ()
methode van de ContactView
klasse zodat het de webservice op de hoogte stelt wanneer een contact wordt bewerkt; verander de regel code die de set ()
methode zodat het zo lijkt:
this.model.set (formdata) .save ();
Alles wat we doen is het opslaan()
methode op naar de set ()
methode. De opslaan()
methode afgevaardigden naar de synchroniseren()
methode die een POST-aanvraag naar de server doet. Zoals eerder de ID kaart
van het model wordt verzonden als een querystring en een X-HTTP-methode-Override
wordt gebruikt om de beoogde PUT-methode op te geven. Deze keer echter, de Content-Type
koptekst is ingesteld op application / x-www-form-urlencoded
(als we het niet hebben geconfigureerd emulateJSON
eigendom zou het zijn application / json
) en de modelgegevens worden verzonden als formuliergegevens, die we kunnen gebruiken om de wijzigingen aan te brengen die nodig zijn.
Het enige dat u hoeft te doen aan de front-end is het bijwerken van Cont.persToev ()
methode van de DirectoryView
klasse. Eerder in deze methode hadden we een if-instructie die het type model controleerde dat werd toegevoegd om te zien of het geselecteerde menu moest worden bijgewerkt. Dat moeten we nu als statement wijzigen, zodat het als volgt verschijnt:
if (_.indexOf (this.getTypes (), formData.type) === -1) this. $ el.find ("# filter"). find ("select"). remove (). end () .append (this.createSelect ()); this.collection.create (formData);
We hebben de als
statement omlaag om het te verwijderen anders
voorwaarde, waardoor de code een beetje opgeruimd. We hebben ook het toevoegen()
methode en de create ()
methode in de plaats. De create ()
methode zal het nieuwe model feitelijk automatisch toevoegen aan de verzameling zonder dat we handmatig een nieuw exemplaar van de klasse van ons model maken, en het zal ook een verzoek naar de server doen, opnieuw delegeren naar synchroniseren()
.
Deze keer de X-HTTP-methode-Override
header hoeft niet te worden ingesteld, omdat POST de methode is die we zouden gebruiken als het verzoek toch werd ingediend bij een RESTful-interface. Zoals met de opslaan()
methode, de modelgegevens doorgegeven aan de create ()
methode wordt als formuliergegevens aan de server geleverd.
Net als bij de code aan de serverzijde die aan het begin van dit deel van de zelfstudie wordt gebruikt om de initiële modeldata in onze app op te starten, valt de code die wordt gebruikt om de verzoeken van Backbone te verwerken en af te handelen buiten het bestek van de zelfstudie. We zijn hier alleen geïnteresseerd in de front-end. Net als voorheen is de webservice die voor deze demo wordt gebruikt opgenomen in het codearchief en is deze volledig van commentaar voorzien, dus kijk hier voor als je geïnteresseerd bent. Ik heb ook een back-up van de database opgenomen, die je moet kunnen herstellen om aan de slag te kunnen met de demogegevens.
In dit deel van de tutorial hebben we gekeken naar enkele van de methoden die we kunnen gebruiken die delegeren naar Backbone synchroniseren()
methode om te communiceren met een back-end die de gemaakte wijzigingen aan de voorkant van de applicatie kan voortzetten.
We hebben gezien hoe Backbone standaard REST-aanvragen maakt voor een opgegeven URL en hoe we dit kunnen configureren om te kunnen werken met oudere servers die niet volgens REST-principes werken. We hebben ook gekeken naar enkele van de methoden waarnaar wordt gedelegeerd synchroniseren()
om met de server te communiceren. Concreet hebben we de verwijderen()
, opslaan()
en create ()
methoden en gekeken naar wat naar de server wordt verzonden en hoe.
We hebben ook gekeken naar hoe gemakkelijk het is om de symbolen te veranderen die Underscore gebruikt om gegevens in een sjabloon te interpoleren. Hiermee wordt nu de zelfstudie van Contact Manager afgesloten; Hoewel er veel meer functies zijn die we aan de toepassing kunnen toevoegen, hebben we nu de basis besproken van wat er nodig is om een volledig functionele applicatie te bouwen met behulp van de uitstekende Backbone.js. Bedankt voor het lezen.