AngularJS samarbetskort med Socket.io

Författare: Peter Berry
Skapelsedatum: 14 Juli 2021
Uppdatera Datum: 13 Maj 2024
Anonim
AngularJS samarbetskort med Socket.io - Kreativ
AngularJS samarbetskort med Socket.io - Kreativ

Innehåll

  • Kunskap som behövs: Mellanliggande JavaScript
  • Kräver: Node.js, NPM
  • Projekttid: 2 timmar

AngularJS är särskilt väl lämpad för att skapa rika applikationer på klientsidan i webbläsaren, och när du lägger till en liten Socket.io i mixen blir det väldigt intressant. I den här artikeln ska vi bygga ett samverkanskort i realtid som använder AngularJS för klientsidan och Socket.io för att dela tillstånd mellan alla anslutna klienter.

Låt oss täcka lite städning innan vi börjar. Jag antar att du har ett grundläggande grepp om HTML och JavaScript eftersom jag inte täcker varje litet hörn av koden. Till exempel kommer jag inte att ropa ut CSS- och JavaScript-filer som jag har inkluderat i HTML-filens huvud eftersom det inte finns någon ny information där.

Jag uppmuntrar dig också att ta tag i koden från mitt GitHub-konto för att följa med. Min goda vän Brian Ford har också ett utmärkt Socket.io-utsäde, som jag baserade några av mina ursprungliga idéer på.

De fyra huvudfunktionerna vi vill ha i samarbetskortet är möjligheten att skapa en anteckning, läsa anteckningarna, uppdatera en anteckning, ta bort en anteckning och, för skojs skull, flytta en anteckning på tavlan. Ja, det stämmer, vi fokuserar på standard CRUD-funktioner. Jag tror att genom att fokusera på dessa grundläggande funktioner kommer vi att ha täckt tillräckligt med kod för att mönster ska dyka upp så att du kan ta dem och tillämpa dem någon annanstans.


01. Servern

Vi kommer att börja med Node.js-servern först eftersom den kommer att tjäna som grund som vi ska bygga allt annat på.

Vi ska bygga en Node.js-server med Express och Socket.io. Anledningen till att vi använder Express är att det ger en bra mekanism för att ställa in en statisk tillgångsserver inom Node.js. Express kommer med en massa riktigt fantastiska funktioner, men i det här fallet ska vi använda den för att halvera applikationen rent mellan servern och klienten.

(Jag arbetar under antagandet att du har Node.js och NPM installerat. En snabb Google-sökning visar hur du installerar dessa om du inte gör det.)

02. De bara benen

Så för att bygga de bara benen på servern måste vi göra ett par saker för att komma igång.

// app.js

// A.1
var express = kräver (’express’),
app = express ();
server = kräver (’http’). createServer (app),
io = kräver ('socket.io'). lyssna (server);

// A.2
app.configure (funktion () {
app.use (express.static (__ dirname + ’/ public’));
});

// A.3
server.listen (1337);


A.1 Vi förklarar och installerar våra Node.js-moduler så att vi kan använda dem i vår applikation. Vi förklarar Express, initierar Express och skapar sedan en HTTP-server och skickar in Express-instansen till den. Och därifrån startar vi Socket.io och säger att den ska hålla ett öga på vår serverinstans.

A.2 Vi säger sedan till vår Express-app att använda vår offentliga katalog för att betjäna filer från.

A.3 Vi startar servern och säger att den ska lyssna på port 1337.

Hittills har det varit ganska smärtfritt och snabbt. Jag tror att vi har mindre än 10 rader i koden och redan har vi en funktionell Node.js-server. framåt!

03. Förklara dina beroende

// Packages.json
{
"name": "vinkel-collab-board",
"description": "AngularJS Collaboration Board",
"version": "0.0.1-1",
"privat": sant,
"beroenden": {
"express": "3.x",
"socket.io": "0.9.x"
}
}

En av de trevligaste funktionerna i NPM är förmågan att deklarera dina beroenden i en Packages.json filen och installera dem automatiskt via npm installera på kommandoraden.


04. Anslut Socket.io

Vi har redan definierat de kärnfunktioner som vi vill ha i applikationen och därför måste vi ställa in Socket.io-evenemangslyssnare och en lämplig avslutning för att hantera händelsen för varje operation.

I koden nedan kommer du att märka att det i huvudsak är en konfiguration av eventlyssnare och återuppringningar. Den första händelsen är förbindelse händelse, som vi använder för att leda upp våra andra händelser i avslutningen.

io.sockets.on ('anslutning', funktion (socket) {
socket.on ('createNote', funktion (data) {
socket.broadcast.emit ('onNoteCreated', data);
});

socket.on ('updateNote', funktion (data) {
socket.broadcast.emit ('onNoteUpdated', data);
});

socket.on ('deleteNote', funktion (data) {
socket.broadcast.emit ('onNoteDeleted', data);
});

socket.on ('moveNote', funktion (data) {
socket.broadcast.emit ('onNoteMoved', data);
});
});

Härifrån lägger vi till lyssnare till createNote, updateNote, deleteNote och moveNote. Och i återuppringningsfunktionen sänder vi helt enkelt vilken händelse som hänt så att alla klienter som lyssnar kan meddelas att händelsen inträffade.

Det finns några saker som är värda att påpeka om återuppringningsfunktionerna i de enskilda evenemangshanterarna. En om du vill skicka en händelse till alla andra utom klienten som släppte händelsen du infogar utsända Innan avge funktionssamtal. För det andra skickar vi helt enkelt nyttolasten till evenemanget till de intresserade så att de kan bearbeta det enligt deras önskemål.

05. Starta dina motorer!

Nu när vi har definierat våra beroenden och konfigurerat vår Node.js-applikation med Express- och Socket.io-befogenheter är det ganska enkelt att initiera Node.js-servern.

Först installerar du dina Node.js-beroenden så:

npm installera

Och sedan startar du servern så här:

nod app.js

Och då! Du går till den här adressen i din webbläsare. Bam!

06. Några uppriktiga tankar innan vi går vidare

Jag är främst en frontend-utvecklare och jag blev initialt lite skrämd med att ansluta en Node.js-server till min applikation. AngularJS-delen var en snabb men JavaScript-sida på serversidan? Kö den läskiga musiken från en skräckfilm.

Men jag hade absolut golvet för att upptäcka att jag kunde ställa in en statisk webbserver på bara några rader kod och på några fler rader använda Socket.io för att hantera alla händelser mellan webbläsarna. Och det var fortfarande bara JavaScript! För aktualitetens skull täcker vi bara några få funktioner, men jag hoppas att det i slutet av artikeln kommer att se att det är lätt att simma - och den djupa änden av poolen är inte så läskig.

07. Klienten

Nu när vi har vår solida grund på plats med vår server, går vi vidare till min favoritdel - klienten! Vi kommer att använda AngularJS, jQueryUI för den dragbara delen och Twitter Bootstrap för en stilbas.

08. De bara benen

När det gäller en personlig AngularJS-applikation vill jag snabbt definiera det minsta minimum som jag vet att jag behöver för att komma igång och sedan börja itera över det så snabbt som möjligt.

Varje AngularJS-applikation måste startas med minst en kontroller närvarande, så det här är vanligtvis där jag alltid börjar.

För att starta om applikationen automatiskt måste du helt enkelt lägga till ng-app till HTML-noden där du vill att applikationen ska leva. För det mesta kommer det att vara helt acceptabelt att lägga till det i HTML-taggen. Jag har också lagt till ett attribut till ng-app att berätta att jag vill använda app modul, som jag kommer att definiera på ett ögonblick.

// public / index.html
html ng-app = "app">

Jag vet att jag kommer att behöva minst en styrenhet och så kommer jag att ringa upp det med hjälp av ng-controller och tilldela den en egendom av MainCtrl.

body ng-controller = "MainCtrl"> / body>

Så nu är vi ute efter en modul som heter app och en styrenhet som heter MainCtrl. Låt oss gå vidare och skapa dem nu.

Att skapa en modul är ganska enkelt. Du definierar det genom att ringa vinkelmodul och ge det ett namn. För framtida referens är den andra parametern i en tom matris där du kan injicera undermoduler för användning i applikationen. Det omfattas inte av denna handledning, men är praktiskt när din applikation börjar växa i komplexitet och behov.

// public / js / collab.js
var app = angular.module (’app’, []);

Vi kommer att förklara några tomma platshållare i app modulen börjar med MainCtrl Nedan.Vi kommer att fylla i allt senare men jag ville illustrera den grundläggande strukturen från början.

app.controller ('MainCtrl', funktion ($ scope) {});

Vi kommer också att sätta in Socket.io-funktionaliteten i en uttag tjänsten så att vi kan kapsla in objektet och inte låta det flyta runt på det globala namnområdet.

app.factory ('socket', funktion ($ rootScope) {});

Och medan vi håller på med det kommer vi att förklara att ett direktiv kallas fästis som vi ska använda för att inkapsla fästisfunktionaliteten i.

app.directive (”stickyNote”, funktion (uttag) {});

Så låt oss granska vad vi har gjort hittills. Vi har startat applikationen med ng-app och förklarade vår applikationskontroll i HTML. Vi har också definierat applikationsmodulen och skapat MainCtrl styrenhet, den uttag service och fästis direktiv.

09. Skapa en anteckning

Nu när vi har skelettet av AngularJS-applikationen på plats kommer vi att börja bygga ut skapningsfunktionen.

app.controller ('MainCtrl', funktion ($ scope, socket) {// B.1
$ scope.notes = []; // B.2

// Inkommande
socket.on ('onNoteCreated', funktion (data) {// B.3
$ scope.notes.push (data);
});

// Utgående
$ scope.createNote = funktion () {// B.4
var note = {
id: nytt datum (). getTime (),
titel: 'New Note',
body: 'Väntar'
};

$ scope.notes.push (not);
socket.emit ('createNote', not);
};

B.1 AngularJS har en funktion för beroendeinjicering inbyggd i den så att vi injicerar a $ scope objekt och uttag service. De $ scope objekt fungerar som en ViewModel och är i grunden ett JavaScript-objekt med några händelser bakade i det för att möjliggöra tvåvägs databinding.

B.2 Vi förklarar den matris som vi kommer att använda för att binda vyn till.

B.3 Vi lägger till en lyssnare för onNoteCreated händelse på uttag service och skjuter händelsens nyttolast in i $ scope.notes array.

B.4 Vi har förklarat a createNote metod som skapar en standard notera och skjuter in det i $ scope.notes array. Den använder också uttag tjänsten för att avge createNote händelse och klara ny anteckning föremål längs.

Så nu när vi har en metod för att skapa anteckningen, hur kallar vi det? Det är en bra fråga! I HTML-filen lägger vi till det inbyggda AngularJS-direktivet ng-klicka till knappen och lägg sedan till createNote metodanrop som attributvärde.

button id = "createButton" ng-click = "createNote ()"> Skapa anteckning / knapp>

Dags för en snabb genomgång av vad vi har gjort hittills. Vi har lagt till en array i $ scope objekt i MainCtrl det kommer att innehålla alla anteckningar för applikationen. Vi har också lagt till en createNote metod på $ scope motsätter sig att skapa en ny lokal anteckning och sedan sända den anteckningen till de andra klienterna via uttag service. Vi har också lagt till en eventlyssnare på uttag tjänst så att vi kan veta när andra kunder har skapat en anteckning så att vi kan lägga till den i vår samling.

10. Visa klisterlappar

Vi har nu möjlighet att skapa ett anteckningsobjekt och dela det mellan webbläsare men hur visar vi det faktiskt? Det är här direktiv kommer in.

Direktiv och deras invecklade saker är ett stort ämne, men den korta versionen är att de ger ett sätt att utöka element och attribut med anpassad funktionalitet. Direktiv är lätt min favoritdel om AngularJS eftersom det låter dig i princip skapa en hel DSL (Domain Specific Language) runt din applikation i HTML.

Det är naturligt att eftersom vi ska skapa klisterlappar för vårt samarbetsbräde att vi ska skapa en fästis direktiv. Direktiv definieras genom att anropa direktivmetoden på en modul som du vill deklarera och skicka in ett namn och en funktion som returnerar ett direktivs definitionsobjekt. Direktivets definitionsobjekt har många möjliga egenskaper som du kan definiera på det, men vi kommer bara att använda några för våra ändamål här.

Jag rekommenderar att du tittar på AngularJS-dokumentationen för att se hela listorna med egenskaper som du kan definiera på direktivets definitionsobjekt.

app.directive (”stickyNote”, funktion (uttag) {
var linker = funktion (scope, element, attrs) {};

var controller = funktion ($ scope) {};

lämna tillbaka {
begränsa: ”A”, // C.1
länk: länkare, // C.2
styrenhet: styrenhet, // C.3
omfattning: {// C.4
anmärkning: ’=’,
ondelete: '&'
}
};
});

C.1 Du kan begränsa ditt direktiv till en viss typ av HTML-element. De två vanligaste är element eller attribut som du förklarar att du använder E och A respektive. Du kan också begränsa den till en CSS-klass eller en kommentar, men dessa är inte lika vanliga.

C.2 Länkfunktionen är där du placerar all din DOM-manipulationskod. Det finns några undantag som jag har hittat, men det är alltid sant (minst 99 procent av tiden). Detta är en grundläggande grundregel för AngularJS och det är därför jag har betonat det.

C.3 Kontrollfunktionen fungerar precis som huvudkontrollen som vi definierade för applikationen men $ scope objektet vi skickar in är specifikt för DOM-elementet som direktivet lever vidare.

C.4 AngularJS har ett koncept av isolerad räckvidd, som låter dig uttryckligen definiera hur ett direktivs räckvidd kommunicerar med omvärlden. Om vi ​​inte hade förklarat räckvidd skulle direktivet implicit ha ärvt från föräldraområdet med ett förhållande mellan förälder och barn. I många fall är detta inte optimalt. Genom att isolera räckvidden minskar vi chansen att omvärlden oavsiktligt och negativt kan påverka ditt direktivs tillstånd.

Jag har förklarat tvåvägs databindande till notera med = symbol och ett uttryck som binder till ondelete med & symbol. Läs AngularJS-dokumentationen för en fullständig förklaring av det isolerade omfånget eftersom det är ett av de mer komplicerade ämnena i ramverket.

Så låt oss faktiskt lägga till en anteckning till DOM.

Liksom alla bra ramar kommer AngularJS med några riktigt bra funktioner direkt ur lådan. En av de smidigaste funktionerna är ng-upprepa. Detta AngularJS-direktiv låter dig skicka in en uppsättning objekt och det duplicerar vilken tagg det är på så många gånger som det finns objekt i matrisen. I fallet nedan itererar vi över anteckningar array och duplicering av div element och dess barn för längden på anteckningar array.

div stick-note ng-repeat = "note in notes" note = "note" ondelete = "deleteNote (id)">
button type = "button" ng-click = "deleteNote (note.id)"> × / button>
input ng-model = "note.title" ng-change = "updateNote (note)" type = "text">
textarea ng-model = "note.body" ng-change = "updateNote (note)"
> {{note.body}} / textarea>
/ div>

Skönheten i ng-upprepa är att den är bunden till vilken matris du passerar in och när du lägger till ett objekt i matrisen uppdateras ditt DOM-element automatiskt. Du kan ta detta ett steg längre och upprepa inte bara standard DOM-element utan även andra anpassade direktiv. Det är därför du förstår fästis som attribut på elementet.

Det finns två andra bitar av anpassad kod som måste klargöras. Vi har isolerat räckvidden på klisterlappar direktivet om två fastigheter. Den första är det bindande definierade isolerade omfånget på notera fast egendom. Detta betyder att när anteckningsobjektet ändras i det överordnade omfånget kommer det automatiskt att uppdatera motsvarande anteckningsobjekt i direktivet och vice versa. Det andra definierade isolerade omfånget finns på ondelete attribut. Vad detta betyder är att när ondelete kallas i direktivet, kommer det att kalla vad som helst uttryck i ondelete attribut på DOM-elementet som direktiverar direktivet.

När ett direktiv initieras läggs det till i DOM och länkfunktionen anropas. Det här är ett perfekt tillfälle att ställa in några standard DOM-egenskaper på elementet. Elementparametern vi skickar in är faktiskt ett jQuery-objekt och så att vi kan utföra jQuery-operationer på det.

(AngularJS kommer faktiskt med en delmängd av jQuery inbyggd i den men om du redan har inkluderat den fullständiga versionen av jQuery kommer AngularJS att skjuta upp det.)

app.directive (”stickyNote”, funktion (uttag) {
var linker = funktion (scope, element, attrs) {
// Någon DOM-initiering för att göra det trevligt
element.css ('vänster', '10px');
element.css ('top', '50px');
element.hide (). fadeIn ();
};
});

I koden ovan placerar vi helt enkelt klisterlappen på scenen och tappar in den.

11. Ta bort en klisterlapp

Så nu när vi kan lägga till och visa en fästis är det dags att ta bort fästisar. Skapande och radering av klisterlappar handlar om att lägga till och ta bort objekt från matrisen som anteckningarna är bundna till. Det här är föräldrarnas ansvar att behålla den matrisen, varför vi kommer från begäran om borttagning från direktivet, men låter föräldraområdet göra det tunga lyftet.

Det är därför vi har gått igenom alla problem med att skapa uttrycksdefinierat isolerat omfång på direktivet: så att direktivet kan ta bort borttagningshändelsen internt och vidarebefordra det till sin förälder för bearbetning.

Lägg märke till HTML i direktivet.

button type = "button" ng-click = "deleteNote (note.id)"> × / button>

Det nästa jag tänker säga kan verka långt, men kom ihåg att vi är på samma sida och det är vettigt när jag har utarbetat det. När du klickar på knappen i det övre högra hörnet av klisterlappen ringer vi deleteNote på direktivets styrenhet och passera in note.id värde. Styrenheten ringer sedan ondelete, som sedan utför vilket uttryck vi kopplade till det. Än så länge är allt bra? Vi kallar en lokal metod på styrenheten som sedan överlämnar den till genom att anropa vilket uttryck som definierades i det isolerade omfånget. Uttrycket som kallas på föräldern råkar bara kallas deleteNote också.

app.directive (”stickyNote”, funktion (uttag) {
var controller = funktion ($ scope) {
$ scope.deleteNote = funktion (id) {
$ scope.ondelete ({
jag gjorde
});
};
};

lämna tillbaka {
begränsa: ”A”,
länk: länkare,
styrenhet: styrenhet,
omfattning: {
anmärkning: ’=’,
ondelete: '&'
}
};
});

(När du använder uttrycksdefinierat isolerat omfång skickas parametrar i en objektkarta.)

I det överordnade området deleteNote ringer och gör en ganska standard radering med vinkel. för varje verktygsfunktion för att iterera över anteckningsmatrisen. När funktionen väl har hanterat sin lokala verksamhet fortsätter den och avger evenemanget för resten av världen att reagera därefter.

app.controller ('MainCtrl', funktion ($ scope, socket) {
$ scope.notes = [];

// Inkommande
socket.on ('onNoteDeleted', funktion (data) {
$ scope.deleteNote (data.id);
});

// Utgående
$ scope.deleteNote = funktion (id) {
var oldNotes = $ scope.notes,
newNotes = [];

angular.forEach (oldNotes, function (note) {
if (note.id! == id) newNotes.push (note);
});

$ scope.notes = newNotes;
socket.emit (’deleteNote’, {id: id});
};
});

12. Uppdatera en anteckning

Vi gör fantastiska framsteg! Nu hoppas jag att du börjar se några mönster fram från denna virvelvindstur vi tar. Nästa punkt på listan är uppdateringsfunktionen.

Vi kommer att börja med de faktiska DOM-elementen och följa upp det hela vägen till servern och tillbaka till klienten. Först måste vi veta när titeln eller brödtexten för klisterlappen ändras. AngularJS behandlar formelement som en del av datamodellen så att du kan koppla ihop tvåvägs databindning på ett ögonblick. Använd detta för att göra detta ng-modell direktivet och lägg i den egendom du vill binda till. I det här fallet ska vi använda note.title och not. kropp respektive.

När någon av dessa egenskaper ändras vill vi fånga den informationen för att skicka vidare. Vi åstadkommer detta med ng-förändring direktivet och använda det för att ringa updateNote och skicka in själva anteckningsobjektet. AngularJS gör en mycket smart smutsig kontroll för att upptäcka om värdet på vad som helst finns i ng-modell har ändrats och kör sedan uttrycket i ng-förändring.

input ng-model = "note.title" ng-change = "updateNote (note)" type = "text">
textarea ng-model = "note.body" ng-change = "updateNote (note)"> {{note.body}} / textarea>

Uppsidan av att använda ng-förändring är att den lokala omvandlingen redan har hänt och vi är bara ansvariga för att vidarebefordra meddelandet. I styrenheten, updateNote kallas och därifrån kommer vi att släppa ut updateNote händelse för vår server att sända till de andra klienterna.

app.directive (”stickyNote”, funktion (uttag) {
var controller = funktion ($ scope) {
$ scope.updateNote = funktion (not) {
socket.emit (”updateNote”, not);
};
};
});

Och i direktivkontrollen lyssnar vi efter onNoteUpdated händelse att veta när en anteckning från en annan klient har uppdaterats så att vi kan uppdatera vår lokala version.

var controller = funktion ($ scope) {
// Inkommande
socket.on ('onNoteUpdated', funktion (data) {
// Uppdatera om samma anteckning
if (data.id == $ scope.note.id) {

$ scope.note.title = data.title;
$ scope.note.body = data.body;
}
});
};

13. Flytta en klisterlapp

Vid den här tiden har vi i princip gjort ett varv runt barnpoolen CRUD och livet är bra! Bara för att göra ett salongtrick för att imponera på dina vänner kommer vi att lägga till möjligheten att flytta anteckningar runt skärmen och uppdatera koordinater i realtid. Var inte panik - det är bara några fler kodrader. Allt detta hårda arbete kommer att löna sig. Jag lovar!

Vi har bjudit in särskild gäst, jQueryUI, till festen och vi gjorde allt för draggablesna. Att lägga till möjligheten att dra en anteckning lokalt tar bara en rad kod. Om du lägger till element.draggable (); till din länkfunktion kommer du att börja höra ”Eye of the Tiger” av Survivor eftersom du nu kan dra dina anteckningar.

Vi vill veta när släpningen har slutat och fånga de nya koordinaterna för att passera. jQueryUI byggdes av några mycket smarta människor, så när släpningen slutar behöver du helt enkelt definiera en återuppringningsfunktion för stopphändelsen. Vi tar tag i note.id av omfångsobjektet och vänster och övre CSS-värden från ui objekt. Med den kunskapen gör vi det vi har gjort hela tiden: släpp ut!

app.directive (”stickyNote”, funktion (uttag) {
var linker = funktion (scope, element, attrs) {
element.draggable ({
stopp: funktion (händelse, ui) {
socket.emit ('moveNote', {
id: scope.note.id,
x: ui.position. vänster,
y: ui.position.top
});
}
});

socket.on ('onNoteMoved', funktion (data) {
// Uppdatera om samma anteckning
if (data.id == scope.note.id) {
element.animate ({
vänster: data.x,
överst: data.y
});
}
});
};
});

Vid denna tidpunkt borde det inte bli någon överraskning att vi också lyssnar på en flyttrelaterad händelse från sockeltjänsten. I det här fallet är det onNoteMoved händelse och om anteckningen är en matchning uppdaterar vi de vänstra och övre CSS-egenskaperna. Bam! Gjort!

14. Bonusen

Detta är ett bonussektion som jag inte skulle ta med om jag inte var helt säker på att du kunde uppnå det på mindre än tio minuter. Vi ska distribuera till en live-server (jag är fortfarande förvånad över hur lätt det är att göra).

Först måste du registrera dig för en gratis Nodejitsu-testversion. Rättegången är gratis i 30 dagar, vilket är perfekt för att få dina fötter blöta.

När du har skapat ditt konto måste du installera jitsu-paketet, vilket du kan göra från kommandoraden via $ npm installera jitsu -g.

Då måste du logga in från kommandoraden via $ jitsu-inloggning och ange dina uppgifter.

Se till att du är i din app direkt, skriv $ jitsu distribuera och gå igenom frågorna. Jag lämnar vanligtvis så mycket som standard som möjligt, vilket innebär att jag ger min ansökan ett namn men inte en underdomän etc.

Och mina kära vänner, det är allt som finns! Du kommer att få URL till din applikation från serverns utdata när den har distribuerats och den är redo att gå.

15. Slutsats

Vi har täckt mycket AngularJS-mark i den här artikeln och jag hoppas att du hade mycket kul i processen. Jag tycker att det är riktigt snyggt vad du kan åstadkomma med AngularJS och Socket.io i cirka 200 rader kod.

Det fanns några saker som jag inte täckte för att fokusera på huvudpunkterna, men jag uppmuntrar dig att dra ner källan och leka med applikationen. Vi har byggt en stark grund, men det finns fortfarande många funktioner du kan lägga till. Få hacking!

Lukas Ruebbelke är en teknikentusiast och är medförfattare till AngularJS in Action for Manning Publications. Hans favorit sak att göra är att få folk lika glada över ny teknik som han är. Han driver Phoenix Web Application User Group och har varit värd för flera hackathons med sina andra partner i brott.

Gillade detta? Läs dessa!

  • Hur man skapar en app
  • Våra favorittypsnitt på webben - och de kostar inte ett öre
  • Upptäck vad som är nästa för Augmented Reality
  • Ladda ner gratis texturer: hög upplösning och redo att användas nu
Intressant På Platsen
Så här startar du en skrivarserver i Windows 10 enkelt
Läs Mer

Så här startar du en skrivarserver i Windows 10 enkelt

krivarervern pelar en integrerad roll i varje företag och organiation. Denna funktion i Window anvarar för att utföra utkriftkommandon via nätverket eller lokalt. krivarervern kan ...
Hur man sätter in video i PowerPoint-presentation
Läs Mer

Hur man sätter in video i PowerPoint-presentation

Att bifoga en video med en PPT är vanligt. Det finn flera PPT-filer där ute med en komplett videobilaga. Men inte många vet om det finn en ådan funktion eller tror bara att det int...
Hur man tar bort lösenord från Excel-fil
Läs Mer

Hur man tar bort lösenord från Excel-fil

Det är mycket vanligt att kydda Excel-filer genom att tälla in öppet löenord och begränninglöenord. Under tiden blir det nödvändigt att ta bort Excel-löeno...