[JS] Tworzymy aplikację JS z wykorzystaniem Backbone.js, część 4 – wysyłanie wiadomości
W dzisiejszym odcinku serii, skupimy się na wysyłaniu wiadomości do sieci społecznościowych Twittera i Facebooka. Ze względu na to, że w jednym miejscu będziemy wykorzystywać dwa różne API, to taka sytuacja będzie wymagała odpowiedniego podejścia do sprawy czyli odpowiedniego przygotowania struktury wiadomości, którą wysyłamy do sieci.
Aplikacja społecznościowa - formularz wiadomości
Zaczniemy od utworzenia kodu HTML dla formularza wysyłkowego wiadomości. Dla uproszczenia, zostaną tam wykorzystane identyfikatory pól. Kod wygląda następująco:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // js/app/template/messageForm.js <form action="#" class="message form"> <ul> <li class="message"> <textarea name="social-message" id="social-message" cols="30" rows="10" placeholder="Treść wiadomości"></textarea> </li> <li class="link url"> <input type="url" name="social-link" id="social-link" placeholder="Adres linka"> </li> <li class="link title"> <input type="text" name="social-title" id="social-title" placeholder="Tytuł linka"> </li> <li class="link description"> <input type="text" name="social-description" id="social-description" placeholder="Opis linka"> </li> <li class="word-counter"> <p><span>Wykorzystano słów: </span><strong></strong></p> </li> <li class="row-fluid checkboxes"> <label for="twitter" class="span2">Twitter</label><input type="checkbox" name="twitter" class="span1" id="checkbox-twitter"/> <label for="facebook" class="span2">Facebook</label><input type="checkbox" name="facebook" class="span1" id="checkbox-facebook"/> </li> <li class="buttons"> <button class="submit btn positive">Wyślij wiadomość</button> <button class="clear btn tentative">Wyczyść formularz</button> <button class="cancel btn negative">Zaniechaj</button> </li> </ul> </form> |
Jak widać zdefiniowano 4 pola tekstowe, 2 checkboxy oraz 3 przyciski. Dla naszych potrzeb jest to zdecydowanie wystarczające. Oczywiście, można taki formularz rozszerzyć poprzez dodanie do pól tekstowych reguł walidacyjnych w HTML5 czy też opisów WAI-ARIA.
Backbone.js - Wysyłanie wiadomości do sieci społecznościowej
Mając przygotowany szablon HTML dla formularza wysyłkowego, możemy przystąpić do tworzenia kodu JS dla widoku odpowiedzialnego za obsługę formularza. Dla ułatwienia, kod został skomentowany przeze mnie za pomocą komentarzy w kodzie.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | // js/app/view/messageForm.js (function () { 'use strict'; APP.view = APP.view || {}; APP.view.MessageForm = Backbone.View.extend({ el : $('body').find('main'), container : $('<div/>').prop({ id : 'message-form' }), events : { 'click.APP .submit' : 'submit', 'click.APP .cancel' : 'cancel', 'click.APP .clear' : 'clear' }, initialize : function () { this.render(); }, render : function () { console.info('Loading MessageForm view'); // ładujemy szablon HTML dla widoku formularza var form = APP.loadTemplate('messageForm', {}); // usuwamy odwołanie do starego, aktywnego widoku APP.App.destroyActiveView(this.container); // wstawiamy wygenerowany kod HTML formularza do kontenera this.container.empty().append(form); // ustawiamy odwołanie do nowego, aktywnego widoku APP.App.setActiveView(this); // wstawiamy kontener z formularzem do widoku this.$el.append(this.container); }, submit : function (event) { event.preventDefault(); var that = this; // znajdujemy wszystkie zaznaczone checkboxy var checkboxes = this.$el.find('.checkboxes').find('input[type=checkbox]:checked'); // funkcja, która wyświetli wiadomość w oknie aplikacji // o tym czy wysyłka wiadomości do sieci społecznościowych // zakończyła się sukcesem czy nie var createMessage = function (text, type) { console.info('Creating message. Type: ', type); var alertMessage = $('<div/>').prop({ className : type === 'success' ? 'alert alert-success' : 'alert alert-error' }).html(text); that.container.prepend(alertMessage); // po 5 sekundach zakończ wyświetlanie wiadomości setTimeout(function () { that.container.find('.alert').remove(); }, 5000); }; // jeśli jest jakikolwiek checkbox zaznaczony if (checkboxes.length) { // dla każdego z nich _.each(checkboxes, function (checkbox) { // pobierz nazwę sieci społecznościowej var socialName = $(checkbox).prop('name'); // jeśli jest to Twitter if (socialName === 'twitter') { // przygotuj treść statusu na Twittera // pobierz wiadomość oraz zawartość pola z linkiem var params = { status : that.container.find('#social-message').val() + ' ' + that.container.find('#social-link').val() }; // wyślij status do Twittera APP.twitter.__call('statuses_update', params, function (reply) { // jeśli zakńczony sukcesem if (reply.httpstatus === 200) { createMessage('Twitter: Message was sent successfully', 'success'); } else { // jeśli jest błąd to go wyświetl w konsoli createMessage('Twitter: Sending message failed. HTTP Status: ' + reply.httpstatus, reply.error); } }); } else if (socialName === 'facebook') { // jeśli jest to Facebook // id profilu lub fanpage'a na Facebooku var profilID = 15XXXXXXXXXXXXX; // link do grafu wybranego profilu var graphURI = '/' + profilID + '/feed'; // przygotowujemy parametry bazowe z treścią wiadomości var parameters = { message : that.container.find('#social-message').val() }; // jeśli wszystkie pola związane z linkiem (adres URL, tytuł i opis linka) nie są puste if (!_.isEmpty(that.container.find('#social-title').val()) && !_.isEmpty(that.container.find('#social-link').val()) && !_.isEmpty(that.container.find('#social-description').val())) { parameters.name = that.container.find('#social-title').val(); parameters.link = that.container.find('#social-link').val(); parameters.description = that.container.find('#social-description').val(); // wysyłana wiadomość zawiera link parameters.type = 'link'; // i ma być wstawiona na ścianę profilu parameters.status_type = 'wall_post'; // link do grafu profilu z linkami graphURI = '/' + profilID + '/links'; } // wysyłamy wiadomość do Facebooka APP.facebook.api(graphURI, 'post', parameters, function (response) { console.info('Facebook submit response:', response); // jeśli w odpowiedzi jest informacja o błędzie if (response.error) { createMessage('Facebook: Sending messsage failed', 'error'); } else { // jeśli nie createMessage('Facebook: Message was sent successfully', 'success'); this.$el.find(':input').val(''); } }); } }); } }, // funkcja obsługująca zdarzenie zaniechania wysłania wiadomości // wyświetli wtedy widok z Twitterem cancel : function (event) { event.preventDefault(); APP.App.navigation.showTwitter(); }, // funkcja czyszcząca wszystkie pola tekstowe clear : function (event) { event.preventDefault(); this.$el.find(':input').val(''); } }); })(); |
W powyższym kawałku kodu zdefiniowaliśmy obsługę kliknięć dla 3-ch różnych typów zdarzeń: submit, cancel i clear. Aplikacja rozpoznaje do której sieci społecznościowej ma wysłać nową informację poprzez wykrywanie zaznaczenia checkboxa wraz z przypisaną do niego siecią społecznościową, a następnie wykorzystanie odpowiedniego API do wysyłki wiadomości.
Należy pamiętać o tym, że Twitter nie obsługuje aż tak dużej liczby parametrów wiadomości jak Facebook ze względu na to, że zupełnie odmiennie są przedstawiane wiadomości w obydwu sieciach. Facebook stawia na pełną dokumentację linków, a Twitter stawia na prostotę.
Podsumowanie
To w zasadzie jest wszystko. Należy jednak pamiętać, aby kod w wersji produkcyjnej posiadał odpowiednią walidację danych wpisywanych przez użytkownika, dzięki czemu zabezpieczycie aplikację przed wysyłaniem szkodliwego kodu gdziekolwiek (do bazy danych, do innego użytkownika, itp.).
W kolejnych częściach zostanie omówiony routing wewnątrz aplikacji oraz sposoby optymalizacji aplikacji.