AngularJS ร่วมมือกับ Socket.io

ผู้เขียน: Peter Berry
วันที่สร้าง: 14 กรกฎาคม 2021
วันที่อัปเดต: 13 พฤษภาคม 2024
Anonim
EP 23.0  สร้าง Web Shopping ช่องค้นหาสินค้า และเทคนิค debounceTime และ auditTime - Angular
วิดีโอ: EP 23.0 สร้าง Web Shopping ช่องค้นหาสินค้า และเทคนิค debounceTime และ auditTime - Angular

เนื้อหา

  • ความรู้ที่จำเป็น: JavaScript ระดับกลาง
  • ต้องใช้: Node.js, NPM
  • เวลาโครงการ: 2 ชั่วโมง

AngularJS เหมาะอย่างยิ่งสำหรับการสร้างแอปพลิเคชั่นฝั่งไคลเอ็นต์ที่หลากหลายในเบราว์เซอร์และเมื่อคุณเพิ่ม Socket.io เล็กน้อยเข้าไปในส่วนผสมสิ่งต่างๆก็น่าสนใจมาก ในบทความนี้เราจะสร้างบอร์ดการทำงานร่วมกันแบบเรียลไทม์ที่ใช้ AngularJS สำหรับแอปพลิเคชันฝั่งไคลเอ็นต์และ Socket.io เพื่อแชร์สถานะระหว่างไคลเอนต์ที่เชื่อมต่อทั้งหมด

มาดูเรื่องการดูแลทำความสะอาดกันก่อนเริ่มกันเลย ฉันจะสมมติว่าคุณมีความเข้าใจพื้นฐานของ HTML และ JavaScript เนื่องจากฉันจะไม่พูดถึงทุกซอกมุมของโค้ด ตัวอย่างเช่นฉันจะไม่เรียกไฟล์ CSS และ JavaScript ที่รวมไว้ในส่วนหัวของไฟล์ HTML เนื่องจากไม่มีข้อมูลใหม่ที่นั่น

นอกจากนี้ฉันขอแนะนำให้คุณคว้ารหัสจากบัญชี GitHub ของฉันเพื่อทำตาม ไบรอันฟอร์ดเพื่อนที่ดีของฉันยังมีเมล็ดพันธุ์ Socket.io ที่ยอดเยี่ยมซึ่งฉันใช้แนวคิดดั้งเดิมของฉัน

คุณสมบัติหลักสี่ประการที่เราต้องการในบอร์ดการทำงานร่วมกันคือความสามารถในการสร้างโน้ตอ่านโน้ตอัปเดตโน้ตลบโน้ตและเพื่อความสนุกสนานให้ย้ายโน้ตบนกระดาน ใช่ถูกต้องเรากำลังมุ่งเน้นไปที่คุณลักษณะ CRUD มาตรฐาน ฉันเชื่อว่าการมุ่งเน้นไปที่คุณสมบัติพื้นฐานเหล่านี้เราจะครอบคลุมโค้ดเพียงพอสำหรับรูปแบบที่จะปรากฏเพื่อให้คุณสามารถนำไปใช้ที่อื่นได้


01. เซิฟเวอร์

เราจะเริ่มต้นด้วยเซิร์ฟเวอร์ Node.js ก่อนเนื่องจากจะทำหน้าที่เป็นรากฐานที่เราจะสร้างอย่างอื่นต่อไป

เรากำลังจะสร้างเซิร์ฟเวอร์ Node.js ด้วย Express และ Socket.io เหตุผลที่เราใช้ Express คือมีกลไกที่ดีในการตั้งค่าเซิร์ฟเวอร์เนื้อหาแบบคงที่ภายใน Node.js Express มาพร้อมกับคุณสมบัติที่ยอดเยี่ยมมากมาย แต่ในกรณีนี้เราจะใช้มันเพื่อแบ่งแอปพลิเคชันออกเป็นสองส่วนระหว่างเซิร์ฟเวอร์และไคลเอนต์

(ฉันดำเนินการภายใต้สมมติฐานที่ว่าคุณติดตั้ง Node.js และ NPM การค้นหาโดย Google อย่างรวดเร็วจะแสดงวิธีการติดตั้งสิ่งเหล่านี้หากคุณไม่ได้ติดตั้ง)

02. กระดูกเปลือย

ดังนั้นในการสร้างกระดูกที่เปลือยเปล่าของเซิร์ฟเวอร์เราต้องทำสองสามอย่างเพื่อเริ่มต้นใช้งาน

// app.js

// ก. 1
var express = ต้องใช้ ('ด่วน'),
app = ด่วน ();
เซิร์ฟเวอร์ = ต้องการ ('http'). createServer (แอป),
io = ต้องใช้ ('socket.io') ฟัง (เซิร์ฟเวอร์);

// ก. 2
app.configure (ฟังก์ชัน () {
app.use (express.static (__ dirname + '/ สาธารณะ'));
});

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


A.1 เรากำลังประกาศและสร้างอินสแตนซ์โมดูล Node.js ของเราเพื่อให้เราสามารถใช้งานได้ในแอปพลิเคชันของเรา เรากำลังประกาศ Express สร้างอินสแตนซ์ Express จากนั้นสร้างเซิร์ฟเวอร์ HTTP และส่งอินสแตนซ์ Express เข้าไป และจากนั้นเราจะสร้างอินสแตนซ์ Socket.io และบอกให้จับตาดูอินสแตนซ์เซิร์ฟเวอร์ของเรา

A.2 จากนั้นเราจะแจ้งให้แอป Express ใช้ไดเรกทอรีสาธารณะของเราเพื่อให้บริการไฟล์จาก

A.3 เราเริ่มต้นเซิร์ฟเวอร์และบอกให้ฟังบนพอร์ต 1337.

จนถึงตอนนี้มันค่อนข้างไม่เจ็บปวดและรวดเร็ว ฉันเชื่อว่าเรามีโค้ดน้อยกว่า 10 บรรทัดและเรามีเซิร์ฟเวอร์ Node.js ที่ใช้งานได้แล้ว ต่อไปข้างหน้า!

03. ประกาศการพึ่งพาของคุณ

// package.json
{
"name": "เชิงมุม-collab-board",
"description": "คณะกรรมการความร่วมมือ AngularJS",
"เวอร์ชัน": "0.0.1-1",
"ส่วนตัว": จริง
"การอ้างอิง": {
"ด่วน": "3.x",
"socket.io": "0.9.x"
}
}

หนึ่งในคุณสมบัติที่ดีที่สุดของ NPM คือความสามารถในการประกาศการอ้างอิงของคุณในไฟล์ package.json แล้วติดตั้งโดยอัตโนมัติผ่านไฟล์ npm ติดตั้ง ในบรรทัดคำสั่ง


04. ต่อสาย Socket.io

เราได้กำหนดคุณสมบัติหลักที่เราต้องการในแอปพลิเคชันแล้วดังนั้นเราจึงจำเป็นต้องตั้งค่าตัวฟังเหตุการณ์ Socket.io และการปิดที่เหมาะสมเพื่อจัดการเหตุการณ์สำหรับแต่ละการดำเนินการ

ในโค้ดด้านล่างคุณจะสังเกตเห็นว่าโดยพื้นฐานแล้วเป็นการกำหนดค่าของผู้ฟังเหตุการณ์และการโทรกลับ เหตุการณ์แรกคือ การเชื่อมต่อ เหตุการณ์ที่เราใช้เพื่อเชื่อมโยงเหตุการณ์อื่น ๆ ของเราในการปิด

io.sockets.on ('การเชื่อมต่อ', ฟังก์ชัน (ซ็อกเก็ต) {
socket.on ('createNote', ฟังก์ชัน (ข้อมูล) {
socket.broadcast.emit ('onNoteCreated', ข้อมูล);
});

socket.on ('updateNote', ฟังก์ชัน (ข้อมูล) {
socket.broadcast.emit ('onNoteUpdated', ข้อมูล);
});

socket.on ('deleteNote', ฟังก์ชัน (ข้อมูล) {
socket.broadcast.emit ('onNoteDeleted', ข้อมูล);
});

socket.on ('moveNote', ฟังก์ชัน (ข้อมูล) {
socket.broadcast.emit ('onNoteMoved', ข้อมูล);
});
});

จากที่นี่เราจะเพิ่มผู้ฟังเข้าไป createNote, updateNote, ลบหมายเหตุ และ moveNote. และในฟังก์ชั่นโทรกลับเราเพียงแค่ถ่ายทอดเหตุการณ์ที่เกิดขึ้นเพื่อให้ลูกค้าที่รับฟังสามารถรับแจ้งว่ามีเหตุการณ์เกิดขึ้น

มีบางสิ่งที่ควรพิจารณาเกี่ยวกับฟังก์ชันการเรียกกลับในตัวจัดการเหตุการณ์แต่ละรายการ หนึ่งถ้าคุณต้องการส่งเหตุการณ์ให้คนอื่น แต่ลูกค้าที่ส่งเหตุการณ์ที่คุณแทรก ออกอากาศ ก่อนหน้า เปล่ง การเรียกใช้ฟังก์ชัน ประการที่สองเราเพียงแค่ส่งข้อมูลของเหตุการณ์ไปยังผู้ที่สนใจเพื่อให้พวกเขาดำเนินการตามที่เห็นสมควร

05. สตาร์ทเครื่องยนต์ของคุณ!

ตอนนี้เราได้กำหนดการอ้างอิงและตั้งค่าแอปพลิเคชัน Node.js ด้วยพาวเวอร์ Express และ Socket.io แล้วการเริ่มต้นเซิร์ฟเวอร์ Node.js นั้นค่อนข้างง่าย

ก่อนอื่นคุณต้องติดตั้งการอ้างอิง Node.js ของคุณดังนี้:

npm ติดตั้ง

จากนั้นคุณเริ่มเซิร์ฟเวอร์ดังนี้:

โหนด app.js

แล้ว! คุณไปที่ที่อยู่นี้ในเบราว์เซอร์ของคุณ แบม!

06. คิดตรงไปตรงมาก่อนที่จะก้าวต่อไป

ฉันเป็นนักพัฒนาส่วนหน้าเป็นหลักและในตอนแรกฉันรู้สึกกลัวนิดหน่อยกับการเชื่อมต่อเซิร์ฟเวอร์ Node.js เข้ากับแอปพลิเคชันของฉัน ส่วน AngularJS เป็นสแน็ป แต่ JavaScript ฝั่งเซิร์ฟเวอร์? จัดคิวเพลงที่น่าขนลุกจากภาพยนตร์สยองขวัญ

แต่ฉันรู้สึกประหลาดใจอย่างยิ่งที่พบว่าฉันสามารถตั้งค่าเว็บเซิร์ฟเวอร์แบบคงที่ได้ในโค้ดเพียงไม่กี่บรรทัดและในอีกสองสามบรรทัดใช้ Socket.io เพื่อจัดการเหตุการณ์ทั้งหมดระหว่างเบราว์เซอร์ และมันยังคงเป็นแค่ JavaScript! เพื่อความทันท่วงทีเราจะกล่าวถึงคุณลักษณะบางประการเท่านั้น แต่ฉันหวังว่าในตอนท้ายของบทความคุณจะเห็นว่าการว่ายน้ำเป็นเรื่องง่าย - และส่วนลึกสุดของสระว่ายน้ำก็ไม่ได้น่ากลัวเท่าไหร่

07. ลูกค้า

ตอนนี้เรามีรากฐานที่มั่นคงกับเซิร์ฟเวอร์ของเราแล้วเรามาดูส่วนที่ชื่นชอบกันเลยนั่นก็คือลูกค้า! เราจะใช้ AngularJS, jQueryUI สำหรับส่วนที่ลากได้และ Twitter Bootstrap สำหรับฐานสไตล์

08. กระดูกเปลือย

ตามความชอบส่วนบุคคลเมื่อฉันเริ่มแอปพลิเคชัน AngularJS ใหม่ฉันต้องการกำหนดค่าขั้นต่ำที่เปลือยเปล่าอย่างรวดเร็วซึ่งฉันรู้ว่าฉันจะต้องเริ่มต้นใช้งานจากนั้นเริ่มต้นซ้ำโดยเร็วที่สุด

แอปพลิเคชัน AngularJS ทุกตัวจะต้องบูตด้วยคอนโทรลเลอร์อย่างน้อยหนึ่งตัวซึ่งโดยทั่วไปแล้วนี่เป็นจุดเริ่มต้นของฉันเสมอ

ในการบูตแอปพลิเคชันโดยอัตโนมัติคุณต้องเพิ่ม ng-app ไปยังโหนด HTML ที่คุณต้องการให้แอปพลิเคชันทำงาน โดยส่วนใหญ่แล้วการเพิ่มลงในแท็ก HTML จะเป็นที่ยอมรับอย่างสมบูรณ์ ฉันได้เพิ่มแอตทริบิวต์ให้ด้วย ng-app เพื่อบอกว่าฉันต้องการใช้ไฟล์ แอป โมดูลที่ฉันจะกำหนดในอีกสักครู่

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

ฉันรู้ว่าฉันจะต้องมีคอนโทรลเลอร์อย่างน้อยหนึ่งตัวฉันจึงจะเรียกมันออกมาโดยใช้ ng- ตัวควบคุม และกำหนดให้เป็นคุณสมบัติของ MainCtrl.

ร่างกาย ng-controller = "MainCtrl"> / body>

ตอนนี้เรากำลังเข้าใจโมดูลที่มีชื่อว่า แอป และตัวควบคุมชื่อ MainCtrl. ให้เราไปสร้างมันตอนนี้

การสร้างโมดูลนั้นค่อนข้างตรงไปตรงมา คุณกำหนดโดยการโทร angular.module และตั้งชื่อให้ สำหรับการอ้างอิงในอนาคตพารามิเตอร์ที่สองของอาร์เรย์ว่างคือที่ที่คุณสามารถฉีดโมดูลย่อยเพื่อใช้ในแอปพลิเคชัน มันอยู่นอกขอบเขตของบทช่วยสอนนี้ แต่จะมีประโยชน์เมื่อแอปพลิเคชันของคุณเริ่มมีความซับซ้อนและความต้องการมากขึ้น

// public / js / collab.js
var app = angular.module ('แอป', []);

เรากำลังจะประกาศตัวยึดตำแหน่งว่างสองสามตัวใน แอป โมดูลเริ่มต้นด้วย MainCtrl ด้านล่างเราจะเติมเต็มสิ่งเหล่านี้ในภายหลัง แต่ฉันต้องการแสดงให้เห็นโครงสร้างพื้นฐานตั้งแต่เริ่มมีอาการ

app.controller ('MainCtrl', ฟังก์ชัน ($ scope) {});

นอกจากนี้เรายังจะรวมฟังก์ชัน Socket.io ไว้ในไฟล์ เบ้า บริการเพื่อให้เราสามารถห่อหุ้มวัตถุนั้นและไม่ปล่อยให้มันลอยอยู่บนเนมสเปซส่วนกลาง

app.factory ('ซ็อกเก็ต', ฟังก์ชัน ($ rootScope) {});

และในขณะที่เรากำลังดำเนินการอยู่เราจะประกาศคำสั่งที่เรียกว่า โน้ต ที่เราจะใช้ในการห่อหุ้มฟังก์ชันการทำงานของบันทึกย่อช่วยเตือน

app.directive ('stickyNote', ฟังก์ชัน (ซ็อกเก็ต) {});

ดังนั้นให้เราทบทวนสิ่งที่เราได้ทำไปแล้ว เราได้บูตแอปพลิเคชันโดยใช้ไฟล์ ng-app และประกาศตัวควบคุมแอปพลิเคชันของเราใน HTML นอกจากนี้เรายังได้กำหนดโมดูลแอปพลิเคชันและสร้างไฟล์ MainCtrl ตัวควบคุม, เบ้า บริการและ โน้ต คำสั่ง

09. การสร้างบันทึกย่อช่วยเตือน

ตอนนี้เรามีโครงกระดูกของแอปพลิเคชัน AngularJS แล้วเราจะเริ่มสร้างคุณลักษณะการสร้าง

app.controller ('MainCtrl', ฟังก์ชัน ($ ขอบเขต, ซ็อกเก็ต) {// B.1
$ scope.notes = []; // ข. 2

// ขาเข้า
socket.on ('onNoteCreated', ฟังก์ชัน (ข้อมูล) {// B.3
$ scope.notes.push (ข้อมูล);
});

// ขาออก
$ scope.createNote = function () {// B.4
var note = {
id: วันที่ใหม่ (). getTime (),
ชื่อเรื่อง: "หมายเหตุใหม่"
เนื้อความ: "รอดำเนินการ"
};

$ scope.notes.push (หมายเหตุ);
socket.emit ('createNote', หมายเหตุ);
};

B.1 AngularJS มีคุณลักษณะการฉีดแบบพึ่งพาในตัวดังนั้นเราจึงอัดฉีดไฟล์ ขอบเขต $ วัตถุและ เบ้า บริการ. ขอบเขต $ อ็อบเจ็กต์ทำหน้าที่เป็น ViewModel และโดยพื้นฐานแล้วเป็นอ็อบเจ็กต์ JavaScript ที่มีเหตุการณ์บางอย่างรวมอยู่ในนั้นเพื่อเปิดใช้งานการเชื่อมต่อสองทาง

B.2 เรากำลังประกาศอาร์เรย์ที่เราจะใช้เพื่อเชื่อมโยงมุมมอง

B.3 เรากำลังเพิ่ม Listener สำหรับ onNoteCreated เหตุการณ์ใน เบ้า บริการและผลักภาระเหตุการณ์ไปยังไฟล์ $ scope.notes อาร์เรย์

B.4 เราได้ประกาศก createNote วิธีการที่สร้างค่าเริ่มต้น บันทึก วัตถุและดันเข้าไปในไฟล์ $ scope.notes อาร์เรย์ นอกจากนี้ยังใช้ไฟล์ เบ้า บริการที่จะปล่อยไฟล์ createNote เหตุการณ์และผ่าน บันทึกใหม่ วัตถุพร้อม

ตอนนี้เรามีวิธีสร้างโน้ตแล้วเราจะเรียกมันว่าอย่างไร? นั่นเป็นคำถามที่ดี! ในไฟล์ HTML เราเพิ่มคำสั่ง AngularJS ในตัว ng- คลิก ไปที่ปุ่มแล้วเพิ่มไฟล์ createNote เรียกเมธอดเป็นค่าแอตทริบิวต์

ปุ่ม id = "createButton" ng-click = "createNote ()"> สร้างบันทึก / ปุ่ม>

ถึงเวลาทบทวนสิ่งที่เราได้ทำไปแล้วอย่างรวดเร็ว เราได้เพิ่มอาร์เรย์ในไฟล์ ขอบเขต $ วัตถุในไฟล์ MainCtrl ที่จะเก็บโน้ตทั้งหมดของแอปพลิเคชันไว้ เรายังได้เพิ่มไฟล์ createNote วิธีการบน ขอบเขต $ เพื่อสร้างบันทึกในเครื่องใหม่แล้วถ่ายทอดบันทึกนั้นไปยังไคลเอนต์อื่น ๆ ผ่านทางไฟล์ เบ้า บริการ. นอกจากนี้เรายังได้เพิ่มผู้ฟังเหตุการณ์ในไฟล์ เบ้า บริการเพื่อให้เราสามารถทราบเมื่อลูกค้ารายอื่นได้สร้างบันทึกเพื่อให้เราสามารถเพิ่มลงในคอลเล็กชันของเราได้

10. การแสดงบันทึกย่อช่วยเตือน

ตอนนี้เรามีความสามารถในการสร้างออบเจ็กต์โน้ตและแชร์ระหว่างเบราว์เซอร์ แต่เราจะแสดงมันได้อย่างไร? นี่คือที่มาของคำสั่ง

คำสั่งและความซับซ้อนเป็นเรื่องที่กว้างขวาง แต่เวอร์ชันสั้น ๆ คือมีวิธีการขยายองค์ประกอบและแอตทริบิวต์ด้วยฟังก์ชันการทำงานที่กำหนดเอง Directives เป็นส่วนโปรดของฉันเกี่ยวกับ AngularJS เพราะช่วยให้คุณสามารถสร้าง DSL (ภาษาเฉพาะโดเมน) ทั้งหมดรอบ ๆ แอปพลิเคชันของคุณในรูปแบบ HTML ได้

เป็นเรื่องธรรมดาที่เราจะสร้างโน้ตสำหรับบอร์ดการทำงานร่วมกันของเราเราจึงควรสร้างไฟล์ โน้ต คำสั่ง คำสั่งถูกกำหนดโดยการเรียกใช้เมธอดคำสั่งบนโมดูลที่คุณต้องการประกาศและส่งผ่านชื่อและฟังก์ชันที่ส่งคืนอ็อบเจ็กต์นิยามคำสั่ง ออบเจ็กต์นิยามคำสั่งมีคุณสมบัติที่เป็นไปได้มากมายที่คุณสามารถกำหนดได้ แต่เราจะใช้เพียงบางส่วนเพื่อวัตถุประสงค์ของเราที่นี่

ฉันขอแนะนำให้คุณตรวจสอบเอกสาร AngularJS เพื่อดูรายการคุณสมบัติทั้งหมดที่คุณสามารถกำหนดบนวัตถุนิยามคำสั่ง

app.directive ('stickyNote', ฟังก์ชัน (ซ็อกเก็ต) {
var linker = ฟังก์ชั่น (ขอบเขตองค์ประกอบ Attrs) {};

var controller = function ($ scope) {};

return {
จำกัด : 'A', // C.1
ลิงค์: linker, // C.2
ตัวควบคุม: ตัวควบคุม // C.3
ขอบเขต: {// C.4
หมายเหตุ: ’=’,
ondelete: ’&’
}
};
});

C.1 คุณสามารถ จำกัด คำสั่งของคุณเป็นองค์ประกอบ HTML บางประเภทได้ สองสิ่งที่พบบ่อยที่สุดคือองค์ประกอบหรือแอตทริบิวต์ซึ่งคุณประกาศใช้ และ ตามลำดับ คุณยังสามารถ จำกัด ไว้ที่คลาส CSS หรือความคิดเห็นได้ แต่สิ่งเหล่านี้ไม่เหมือนกัน

C.2 ฟังก์ชั่นลิงค์เป็นที่ที่คุณใส่รหัสการจัดการ DOM ทั้งหมดของคุณ มีข้อยกเว้นบางประการที่ฉันพบ แต่ก็เป็นจริงเสมอ (อย่างน้อย 99 เปอร์เซ็นต์ของเวลา) นี่เป็นกฎพื้นฐานพื้นฐานของ AngularJS และเป็นเหตุผลที่ฉันเน้นย้ำ

C.3 ฟังก์ชั่นคอนโทรลเลอร์ทำงานเหมือนกับคอนโทรลเลอร์หลักที่เรากำหนดไว้สำหรับแอปพลิเคชัน แต่ฟังก์ชัน ขอบเขต $ ออบเจ็กต์ที่เราส่งผ่านนั้นเจาะจงสำหรับองค์ประกอบ DOM ที่คำสั่งใช้งานอยู่

C.4 AngularJS มีแนวคิดเกี่ยวกับขอบเขตที่แยกได้ซึ่งช่วยให้คุณสามารถกำหนดได้อย่างชัดเจนว่าขอบเขตของคำสั่งสื่อสารกับโลกภายนอกอย่างไร หากเราไม่ได้ประกาศขอบเขตคำสั่งจะได้รับการสืบทอดโดยปริยายจากขอบเขตหลักที่มีความสัมพันธ์แม่ลูก ในหลาย ๆ กรณีสิ่งนี้ไม่เหมาะสม การแยกขอบเขตออกไปทำให้เราลดโอกาสที่โลกภายนอกจะเข้ามาโดยไม่ได้ตั้งใจและส่งผลเสียต่อสถานะของคำสั่งของคุณ

ฉันได้ประกาศการผูกข้อมูลสองทางกับ บันทึก กับ = สัญลักษณ์และนิพจน์ที่เชื่อมโยงกับ ondelete กับ & สัญลักษณ์. โปรดอ่านเอกสาร AngularJS สำหรับคำอธิบายทั้งหมดของขอบเขตที่แยกได้เนื่องจากเป็นหนึ่งในหัวข้อที่ซับซ้อนกว่าในเฟรมเวิร์ก

เรามาเพิ่มบันทึกย่อช่วยเตือนให้ DOM กันเถอะ

เช่นเดียวกับเฟรมเวิร์กที่ดี AngularJS มาพร้อมกับคุณสมบัติที่ยอดเยี่ยมบางอย่างทันที หนึ่งในคุณสมบัติที่สะดวกที่สุดคือ ng- ทำซ้ำ. คำสั่ง AngularJS นี้ช่วยให้คุณสามารถส่งผ่านอาร์เรย์ของอ็อบเจ็กต์และทำซ้ำแท็กที่อยู่ในหลาย ๆ ครั้งตามที่มีรายการในอาร์เรย์ ในกรณีด้านล่างเรากำลังทำซ้ำในไฟล์ หมายเหตุ อาร์เรย์และการทำซ้ำไฟล์ div องค์ประกอบและลูกของมันสำหรับความยาวของ หมายเหตุ อาร์เรย์

div โน้ต ng-repeat = "บันทึกในบันทึก" note = "note" ondelete = "deleteNote (id)">
ประเภทปุ่ม = "button" ng-click = "deleteNote (note.id)"> × / button>
อินพุต ng-model = "note.title" ng-change = "updateNote (note)" type = "text">
textarea ng-model = "note.body" ng-change = "updateNote (หมายเหตุ)"
> {{note.body}} / textarea>
/ div>

ความงามของ ng- ทำซ้ำ คือมันถูกผูกไว้กับอาร์เรย์ใด ๆ ที่คุณส่งผ่านและเมื่อคุณเพิ่มรายการลงในอาร์เรย์องค์ประกอบ DOM ของคุณจะอัปเดตโดยอัตโนมัติ คุณสามารถก้าวไปอีกขั้นและทำซ้ำไม่เพียง แต่องค์ประกอบ DOM มาตรฐานเท่านั้น แต่ยังมีคำสั่งที่กำหนดเองอื่น ๆ อีกด้วย นั่นคือเหตุผลที่คุณเห็น โน้ต เป็นแอตทริบิวต์ขององค์ประกอบ

มีโค้ดที่กำหนดเองอีกสองบิตที่ต้องชี้แจง เราได้แยกขอบเขตของไฟล์ โน้ต คำสั่งเกี่ยวกับคุณสมบัติสองประการ อันแรกคือขอบเขตการแยกที่กำหนดไว้โดยมีผลผูกพันบน บันทึก ทรัพย์สิน. ซึ่งหมายความว่าเมื่อใดก็ตามที่วัตถุบันทึกย่อเปลี่ยนแปลงในขอบเขตหลักมันจะอัปเดตวัตถุบันทึกย่อที่เกี่ยวข้องโดยอัตโนมัติในคำสั่งและในทางกลับกัน ขอบเขตการแยกที่กำหนดอื่น ๆ อยู่ในไฟล์ ondelete แอตทริบิวต์ สิ่งนี้หมายความว่าเมื่อ ondelete ถูกเรียกในคำสั่งมันจะเรียกนิพจน์ใด ๆ ที่อยู่ในไฟล์ ondelete แอตทริบิวต์บนองค์ประกอบ DOM ที่สร้างอินสแตนซ์คำสั่ง

เมื่อคำสั่งถูกสร้างอินสแตนซ์ระบบจะเพิ่ม DOM และฟังก์ชันลิงก์ถูกเรียกใช้ นี่เป็นโอกาสที่ดีในการตั้งค่าคุณสมบัติ DOM เริ่มต้นบนองค์ประกอบ พารามิเตอร์องค์ประกอบที่เราส่งผ่านนั้นเป็นวัตถุ jQuery ดังนั้นเราจึงสามารถดำเนินการกับ jQuery ได้

(AngularJS มาพร้อมกับชุดย่อยของ jQuery ในตัว แต่ถ้าคุณรวม jQuery เวอร์ชันเต็มไว้แล้ว AngularJS จะเลื่อนไปตามนั้น)

app.directive ('stickyNote', ฟังก์ชัน (ซ็อกเก็ต) {
var linker = function (ขอบเขตองค์ประกอบ Attrs) {
// การเริ่มต้น DOM บางอย่างเพื่อให้ดี
element.css ("ซ้าย", "10px");
element.css ("ด้านบน", "50px");
element.hide (). fadeIn ();
};
});

ในโค้ดด้านบนเราเพียงแค่วางตำแหน่งโน้ตบนพื้นที่งานและทำให้มันจางลง

11. การลบโน้ต

ตอนนี้เราสามารถเพิ่มและแสดงบันทึกย่อช่วยเตือนได้แล้วก็ถึงเวลาลบบันทึกย่อช่วยเตือน การสร้างและการลบบันทึกย่อช่วยเตือนเป็นเรื่องของการเพิ่มและลบรายการจากอาร์เรย์ที่โน้ตผูกไว้ นี่เป็นความรับผิดชอบของขอบเขตพาเรนต์ในการดูแลอาร์เรย์นั้นซึ่งเป็นสาเหตุที่เราสร้างคำขอลบจากภายในคำสั่ง แต่ให้ขอบเขตพาเรนต์ทำการยกของหนักจริง

นี่คือสาเหตุที่เราประสบปัญหาทั้งหมดในการสร้างนิพจน์ที่กำหนดขอบเขตแยกในคำสั่งดังนั้นคำสั่งสามารถรับเหตุการณ์ลบภายในและส่งต่อไปยังพาเรนต์เพื่อประมวลผล

สังเกต HTML ภายในคำสั่ง

ประเภทปุ่ม = "button" ng-click = "deleteNote (note.id)"> × / button>

สิ่งต่อไปที่ฉันจะพูดอาจดูเหมือนไกล แต่จำไว้ว่าเราอยู่ข้างเดียวกันและมันจะสมเหตุสมผลหลังจากที่ฉันอธิบายอย่างละเอียด เมื่อปุ่มที่มุมขวาบนของโน้ตถูกคลิกเรากำลังโทร ลบหมายเหตุ บนคอนโทรลเลอร์ของคำสั่งและส่งผ่านไฟล์ note.id มูลค่า. จากนั้นคอนโทรลเลอร์ก็โทร ondelete ซึ่งจะเรียกใช้นิพจน์ใด ๆ ที่เราเชื่อมโยงกับมัน จนถึงตอนนี้ดี? เรากำลังเรียกวิธีการเฉพาะที่บนคอนโทรลเลอร์ซึ่งจะส่งต่อให้โดยเรียกนิพจน์ใด ๆ ที่กำหนดไว้ในขอบเขตที่แยกออกมา นิพจน์ที่ถูกเรียกจากผู้ปกครองเกิดขึ้นเพื่อถูกเรียก ลบหมายเหตุ เช่นกัน.

app.directive ('stickyNote', ฟังก์ชัน (ซ็อกเก็ต) {
var controller = function ($ scope) {
$ scope.deleteNote = function (id) {
$ scope.ondelete ({
ฉันทำ
});
};
};

return {
จำกัด : "A",
ลิงค์: ลิงค์เกอร์,
ตัวควบคุม: ตัวควบคุม,
ขอบเขต: {
หมายเหตุ: ’=’,
ondelete: ’&’
}
};
});

(เมื่อใช้ขอบเขตการแยกที่กำหนดโดยนิพจน์พารามิเตอร์จะถูกส่งไปในแผนที่วัตถุ)

ในขอบเขตหลัก ลบหมายเหตุ ได้รับการเรียกและทำการลบมาตรฐานที่เป็นธรรมโดยใช้ไฟล์ angular.forEach ฟังก์ชั่นยูทิลิตี้เพื่อวนซ้ำเหนืออาร์เรย์บันทึกย่อ เมื่อฟังก์ชั่นนี้จัดการธุรกิจในท้องถิ่นได้แล้วก็จะดำเนินการต่อและปล่อยเหตุการณ์ให้คนทั่วโลกตอบสนองตามนั้น

app.controller ('MainCtrl', ฟังก์ชัน ($ ขอบเขต, ซ็อกเก็ต) {
$ scope.notes = [];

// ขาเข้า
socket.on ('onNoteDeleted', ฟังก์ชัน (ข้อมูล) {
$ scope.deleteNote (data.id);
});

// ขาออก
$ scope.deleteNote = function (id) {
var oldNotes = $ scope.notes,
newNotes = [];

angular.forEach (oldNotes ฟังก์ชัน (หมายเหตุ) {
ถ้า (note.id! == id) newNotes.push (หมายเหตุ);
});

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

12. การอัปเดตบันทึกย่อช่วยเตือน

เรากำลังก้าวหน้าอย่างยอดเยี่ยม! ตอนนี้ฉันหวังว่าคุณจะเริ่มเห็นรูปแบบบางอย่างที่เกิดขึ้นจากทัวร์ลมกรดที่เรากำลังดำเนินการอยู่นี้ รายการถัดไปในรายการคือคุณสมบัติการอัปเดต

เราจะเริ่มต้นที่องค์ประกอบ DOM จริงและติดตามไปจนถึงเซิร์ฟเวอร์และกลับลงไปที่ไคลเอนต์ ก่อนอื่นเราต้องทราบเมื่อมีการเปลี่ยนชื่อเรื่องหรือเนื้อหาของบันทึกย่อช่วยเตือน AngularJS ถือว่าองค์ประกอบฟอร์มเป็นส่วนหนึ่งของโมเดลข้อมูลเพื่อให้คุณสามารถเชื่อมโยงข้อมูลแบบสองทางได้ในพริบตา ในการดำเนินการนี้ให้ใช้ไฟล์ ng-model คำสั่งและใส่คุณสมบัติที่คุณต้องการผูกมัด ในกรณีนี้เราจะใช้ note.title และ note.body ตามลำดับ

เมื่อคุณสมบัติอย่างใดอย่างหนึ่งเปลี่ยนไปเราต้องการเก็บข้อมูลนั้นเพื่อส่งต่อ เราทำสิ่งนี้ให้สำเร็จด้วยไฟล์ ng- เปลี่ยน คำสั่งและใช้เพื่อโทร updateNote และส่งผ่านในวัตถุบันทึกย่อนั้นเอง AngularJS ทำการตรวจสอบสกปรกที่ชาญฉลาดเพื่อตรวจสอบว่ามีค่าของอะไรอยู่หรือไม่ ng-model มีการเปลี่ยนแปลงและเรียกใช้นิพจน์ที่อยู่ใน ng- เปลี่ยน.

อินพุต ng-model = "note.title" ng-change = "updateNote (note)" type = "text">
textarea ng-model = "note.body" ng-change = "updateNote (note)"> {{note.body}} / textarea>

ข้อดีของการใช้ ng- เปลี่ยน นั่นคือการเปลี่ยนแปลงในท้องถิ่นได้เกิดขึ้นแล้วและเรามีหน้าที่เพียงแค่ถ่ายทอดข้อความ ในตัวควบคุม updateNote ถูกเรียกและจากนั้นเราจะปล่อยไฟล์ updateNote เหตุการณ์สำหรับเซิร์ฟเวอร์ของเราเพื่อออกอากาศไปยังไคลเอนต์อื่น ๆ

app.directive ('stickyNote', ฟังก์ชัน (ซ็อกเก็ต) {
var controller = function ($ scope) {
$ scope.updateNote = function (หมายเหตุ) {
socket.emit ('updateNote', หมายเหตุ);
};
};
});

และในตัวควบคุมคำสั่งเรากำลังฟังไฟล์ onNoteUpdated เหตุการณ์ที่ควรทราบเมื่อมีการอัปเดตบันทึกย่อจากลูกค้ารายอื่นเพื่อให้เราสามารถอัปเดตเวอร์ชันท้องถิ่นของเราได้

var controller = function ($ scope) {
// ขาเข้า
socket.on ('onNoteUpdated', ฟังก์ชัน (ข้อมูล) {
// อัปเดตหากโน้ตเดียวกัน
ถ้า (data.id == $ scope.note.id) {

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

13. การย้ายบันทึกย่อช่วยเตือน

เมื่อมาถึงจุดนี้เราได้ทำการตักรอบสระว่ายน้ำตัวเล็ก CRUD และชีวิตก็ดี! เราจะเพิ่มความสามารถในการย้ายโน้ตไปรอบ ๆ หน้าจอและอัปเดตพิกัดแบบเรียลไทม์เพื่อประโยชน์ในการใช้งานห้องนั่งเล่นเพื่อสร้างความประทับใจให้กับเพื่อนของคุณ อย่าเพิ่งตกใจมันเป็นโค้ดอีกไม่กี่บรรทัด งานหนักทั้งหมดนี้กำลังจะได้รับผลตอบแทน ฉันสัญญา!

เราได้เชิญแขกรับเชิญพิเศษ jQueryUI มาร่วมงานปาร์ตี้และเราทำทุกอย่างเพื่อคนลาก การเพิ่มความสามารถในการลากโน้ตในเครื่องจะใช้โค้ดเพียงบรรทัดเดียว หากคุณเพิ่ม element.draggable (); ไปที่ฟังก์ชั่น linker ของคุณคุณจะเริ่มได้ยิน "Eye of the Tiger" โดย Survivor เพราะตอนนี้คุณสามารถลากโน้ตไปรอบ ๆ

เราต้องการทราบว่าเมื่อใดที่การลากหยุดและจับพิกัดใหม่เพื่อส่งต่อ jQueryUI ถูกสร้างขึ้นโดยคนฉลาด ๆ บางคนดังนั้นเมื่อหยุดลากคุณก็ต้องกำหนดฟังก์ชันเรียกกลับสำหรับเหตุการณ์หยุด เราคว้า note.id ปิดวัตถุขอบเขตและค่า CSS ด้านซ้ายและด้านบนจากไฟล์ ui วัตถุ. ด้วยความรู้ที่เราทำในสิ่งที่เราทำมาตลอด: เปล่ง!

app.directive ('stickyNote', ฟังก์ชัน (ซ็อกเก็ต) {
var linker = function (ขอบเขตองค์ประกอบ Attrs) {
element.draggable ({
หยุด: ฟังก์ชัน (เหตุการณ์, ui) {
socket.emit ('moveNote', {
id: scope.note.id,
x: ui.position.left,
y: ui.position.top
});
}
});

socket.on ('onNoteMoved', ฟังก์ชัน (ข้อมูล) {
// อัปเดตหากโน้ตเดียวกัน
ถ้า (data.id == scope.note.id) {
element.animate ({
ซ้าย: data.x,
ด้านบน: data.y
});
}
});
};
});

ณ จุดนี้ไม่น่าแปลกใจเลยที่เรากำลังรับฟังเหตุการณ์ที่เกี่ยวข้องกับการเคลื่อนย้ายจากบริการซ็อกเก็ต ในกรณีนี้คือไฟล์ onNoteMoved เหตุการณ์และหากโน้ตตรงกันเราจะอัปเดตคุณสมบัติ CSS ด้านซ้ายและด้านบน แบม! เสร็จแล้ว!

14. โบนัส

นี่เป็นส่วนโบนัสที่ฉันจะไม่รวมไว้หากฉันไม่มั่นใจอย่างยิ่งว่าคุณจะทำได้ในเวลาไม่ถึง 10 นาที เรากำลังจะปรับใช้กับเซิร์ฟเวอร์ที่ใช้งานจริง (ฉันยังคงประหลาดใจว่ามันง่ายแค่ไหน)

ขั้นแรกคุณต้องลงทะเบียนเพื่อทดลองใช้ Nodejitsu ฟรี ทดลองใช้ฟรี 30 วันซึ่งเหมาะสำหรับการทำให้เท้าเปียก

เมื่อคุณสร้างบัญชีของคุณแล้วคุณจะต้องติดตั้งแพ็คเกจ jitsu ซึ่งคุณสามารถทำได้จากบรรทัดคำสั่งผ่าน $ npm ติดตั้ง jitsu -g.

จากนั้นคุณต้องเข้าสู่ระบบจากบรรทัดคำสั่งผ่าน เข้าสู่ระบบ $ jitsu และป้อนข้อมูลรับรองของคุณ

ตรวจสอบให้แน่ใจว่าคุณอยู่ในแอปของคุณโดยตรงพิมพ์ $ jitsu ปรับใช้ และก้าวผ่านคำถาม ฉันมักจะปล่อยให้เป็นค่าเริ่มต้นให้มากที่สุดซึ่งหมายความว่าฉันตั้งชื่อแอปพลิเคชันของฉัน แต่ไม่ใช่โดเมนย่อยเป็นต้น

และเพื่อนรักของฉันนั่นคือทั้งหมดที่มี! คุณจะได้รับ URL ไปยังแอปพลิเคชันของคุณจากผลลัพธ์ของเซิร์ฟเวอร์เมื่อมีการปรับใช้และพร้อมใช้งาน

15. สรุป

เราได้กล่าวถึงข้อมูล AngularJS มากมายในบทความนี้และฉันหวังว่าคุณจะสนุกกับกระบวนการนี้มาก ฉันคิดว่ามันเป็นสิ่งที่ดีจริงๆที่คุณสามารถทำได้ด้วย AngularJS และ Socket.io ในโค้ดประมาณ 200 บรรทัด

มีบางสิ่งที่ฉันไม่ได้กล่าวถึงเพื่อมุ่งเน้นไปที่ประเด็นหลัก แต่ฉันขอแนะนำให้คุณดึงแหล่งที่มาและเล่นกับแอปพลิเคชัน เราได้สร้างรากฐานที่แข็งแกร่ง แต่ยังมีคุณสมบัติอีกมากมายที่คุณสามารถเพิ่มได้ โดนแฮ็ค!

Lukas Ruebbelke เป็นผู้ที่ชื่นชอบเทคโนโลยีและเป็นผู้ร่วมเขียน AngularJS in Action for Manning Publications สิ่งที่เขาชอบทำคือทำให้ผู้คนตื่นเต้นกับเทคโนโลยีใหม่ ๆ อย่างที่เขาเป็น เขาบริหารกลุ่มผู้ใช้เว็บแอปพลิเคชัน Phoenix และโฮสต์แฮ็กกา ธ อนหลายรายการกับพันธมิตรเพื่อนของเขาในอาชญากรรม

ชอบสิ่งนี้ไหม อ่านสิ่งเหล่านี้!

  • วิธีสร้างแอพ
  • แบบอักษรสำหรับเว็บที่เราชื่นชอบและไม่เสียค่าใช้จ่ายสักบาท
  • ค้นพบสิ่งต่อไปสำหรับ Augmented Reality
  • ดาวน์โหลดพื้นผิวฟรี: ความละเอียดสูงและพร้อมใช้งานทันที
นิยมวันนี้
วิธีใช้สีเพื่อทำให้ภาพประกอบของคุณดูโดดเด่น
อ่าน

วิธีใช้สีเพื่อทำให้ภาพประกอบของคุณดูโดดเด่น

การรักษาสีในภาพประกอบเป็นเรื่องส่วนตัวและไม่ควรปฏิบัติต่อภาพประกอบสองภาพเหมือนกัน หากใช้สีอย่างถูกต้องสามารถดึงภาพที่ชัดเจนซึ่งจะนำภาพประกอบจากสีอ่อนไปเป็นตัวหนาเราจะพูดถึงเคล็ดลับและกลเม็ดเล็ก ๆ น้อย...
ลำโพงบางลงรูปแบบไซต์เพื่อเพิ่มความเร็ว
อ่าน

ลำโพงบางลงรูปแบบไซต์เพื่อเพิ่มความเร็ว

นักออกแบบเว็บไซต์บางคนโดยเฉพาะอย่างยิ่งผู้ที่มีชื่อเสียงในอุตสาหกรรมรู้สึกว่าจำเป็นต้องมีคำชี้แจงเกี่ยวกับการออกแบบบางอย่างเมื่อพวกเขาออกแบบไซต์ส่วนตัวใหม่ มักจะผสมผสานเอฟเฟกต์ภาพเคลื่อนไหวและการเปลี่...
เบื้องหลังของภาพประกอบ 3 มิติสุดหวาดเสียวนี้
อ่าน

เบื้องหลังของภาพประกอบ 3 มิติสุดหวาดเสียวนี้

ในฐานะผู้จัดการผลิตภัณฑ์ในทีมพัฒนาแอปในประเทศจีน Luoqin สร้างงานศิลปะ 3 มิติความละเอียดสูงเป็นงานอดิเรกและบอกว่าความรักใน CG และผลงานชิ้นเอก CG ที่ยอดเยี่ยมทั้งหมดเป็นสิ่งที่ผลักดันให้เขาสร้างภาพประกอ...