1. มันทำอะไร?
บริการ $ ตำแหน่งวิเคราะห์ URL ในแถบที่อยู่ของเบราว์เซอร์ (ขึ้นอยู่กับ Window.Location) ช่วยให้เราสามารถใช้ URL ได้อย่างสะดวกในแอปพลิเคชัน การเปลี่ยน URL ในแถบที่อยู่จะตอบสนองต่อบริการ $ location และการแก้ไข URL ในตำแหน่ง $ จะตอบสนองต่อแถบที่อยู่
$ location service:
เปิดเผย URL ของแถบที่อยู่เบราว์เซอร์ปัจจุบันเพื่อให้เราสามารถทำได้
1. ให้ความสนใจและสังเกต URL
2. เปลี่ยน URL
เมื่อผู้ใช้ทำสิ่งต่อไปนี้ให้ซิงโครไนซ์ URL กับเบราว์เซอร์:
1. เปลี่ยนแถบที่อยู่
2. คลิกปุ่มย้อนกลับหรือไปข้างหน้า (หรือคลิกลิงก์ประวัติศาสตร์)
3. คลิกลิงก์
วิธีการที่อธิบายวัตถุ URL เป็นชุดของวิธีการ (โปรโตคอล, โฮสต์, เส้นทาง, การค้นหา, แฮช)
1. เปรียบเทียบ $ ตำแหน่งและ window.location
1) วัตถุประสงค์: ทั้งสอง window.location และ $ location services อนุญาตให้อ่านและเขียนการเข้าถึงไปยังตำแหน่งของเบราว์เซอร์ปัจจุบัน
2) API: Window.Location เปิดเผยวัตถุที่ยังไม่ผ่านกระบวนการด้วยคุณสมบัติบางอย่างที่สามารถแก้ไขได้โดยตรง ในขณะที่บริการ $ location เปิดเผยวิธีการ getter/setter สไตล์ jQuery
3) การรวมเข้ากับวัฏจักรการประกาศแอปพลิเคชันเชิงมุม: $ ตำแหน่งรู้เกี่ยวกับขั้นตอนวัฏจักรการประกาศภายในทั้งหมดและรวมเข้ากับ $ watch ฯลฯ ; ในขณะที่ Window.location ไม่ทำงาน
4) รวมเข้ากับ HTML5 API ได้อย่างราบรื่น: ด้วยทางเลือกสำหรับเบราว์เซอร์ดั้งเดิมมีวิธีการเข้ากันได้สำหรับเบราว์เซอร์รุ่นที่ต่ำกว่าหรือไม่); ในขณะที่ Window.location ไม่ได้
5) รู้ไดเรกทอรีรูทหรือบริบทของเอกสารที่โหลดโดยแอปพลิเคชัน: Window.location ไม่ทำงานและ wnidow.location.path จะกลับมา "/docroot/subpath"; และ $ location.path () ส่งคืน docroot จริง
2. ฉันควรใช้สถานที่ $ เมื่อใด
ในแอปพลิเคชันทุกครั้งที่คุณต้องตอบสนองต่อการเปลี่ยนแปลง URL ปัจจุบันหรือต้องการเปลี่ยน URL ของเบราว์เซอร์ปัจจุบัน
3. มันไม่ได้ทำอะไร?
เมื่อ URL ของเบราว์เซอร์เปลี่ยนไปหน้าจะไม่โหลดใหม่ หากคุณต้องการทำสิ่งนี้ (เปลี่ยนที่อยู่และใช้การโหลดหน้าใหม่) ให้ใช้ API ระดับล่าง, $ window.location.href
2. ภาพรวมทั่วไปของ API (ภาพรวมโดยรวมของ API)
บริการ $ ตำแหน่งสามารถทำงานแตกต่างกันไปตามการกำหนดค่าเมื่อมีการเริ่มต้น การกำหนดค่าเริ่มต้นเหมาะสำหรับแอปพลิเคชันส่วนใหญ่และการกำหนดค่าอื่น ๆ ได้รับการปรับแต่งซึ่งสามารถเปิดใช้งานคุณสมบัติใหม่บางอย่าง
เมื่อบริการ $ location เริ่มต้นเราสามารถใช้มันในรูปแบบ getter และวิธีการตั้งค่า jQuery ทำให้เราสามารถรับหรือเปลี่ยน URL ของเบราว์เซอร์ปัจจุบัน
1. $ การกำหนดค่าบริการตำแหน่ง
ในการกำหนดค่าบริการ $ ตำแหน่งคุณจะต้องได้รับ $ locationprovider (http://code.angularjs.org/1.0.2/docs/api/ng.$locationprovider) และตั้งค่าพารามิเตอร์ต่อไปนี้:
html5mode (โหมด): {boolean}, true - ดูโหมด html5; FALSE - ดูโหมด Hashbang, ค่าเริ่มต้น: FALSE (บทต่อไปนี้จะอธิบายโหมดต่าง ๆ )
hashprefix (คำนำหน้า): {string}, คำนำหน้าที่ใช้โดย hashbang (เมื่อ html5mode เป็นเท็จให้ใช้โหมด hashbang เพื่อให้เหมาะกับเบราว์เซอร์ที่ไม่รองรับโหมด HTML5), ค่าเริ่มต้น: '!'
2. วิธีการ getter และ setter
บริการ $ location ให้วิธีการ getter สำหรับชิ้นส่วน URL แบบอ่านอย่างเดียว (absurl, โปรโตคอล, โฮสต์, พอร์ต) และยังมีวิธีการ getter และ setter สำหรับ URL, Path, Search และ Hash
// รับเส้นทางปัจจุบัน $ location.path (); // เปลี่ยนเส้นทาง $ location.path ('/newValue')วิธีการตั้งค่าทั้งหมดจะส่งคืนวัตถุที่อยู่ที่ $ เดียวกันเพื่อใช้ไวยากรณ์ที่ถูกล่ามโซ่ ตัวอย่างเช่นแก้ไขแอตทริบิวต์หลายตัวในหนึ่งประโยควิธีการที่ถูกล่ามโซ่จะคล้ายกัน:
$ location.path ('/newValue'). ค้นหา ({คีย์: ค่า});
มีวิธีการแทนที่พิเศษที่สามารถใช้เพื่อบอกบริการ $ ตำแหน่งเพื่อใช้เส้นทางแทนการสร้างประวัติใหม่เมื่อซิงโครไนซ์กับเบราว์เซอร์ในครั้งต่อไปที่คุณจะซิงโครไนซ์กับเบราว์เซอร์ วิธีการแทนที่มีประโยชน์เมื่อเราต้องการใช้การเปลี่ยนเส้นทาง แต่ไม่ต้องการทำให้ปุ่มย้อนกลับเป็นโมฆะ (ปุ่มย้อนกลับกลับมาแล้วเรียกคืนการเปลี่ยนเส้นทาง) หากคุณต้องการเปลี่ยน URL ปัจจุบันโดยไม่ต้องสร้างประวัติใหม่เราสามารถทำได้:
$ location.path ('/somenewpath') แทนที่ ();
โปรดทราบว่าวิธีการตั้งค่าจะไม่อัปเดต window.location ทันที แต่บริการ $ ตำแหน่งจะรู้วงจรชีวิตขอบเขตและรวมการเปลี่ยนแปลงตำแหน่ง $ หลายครั้งเป็นหนึ่งเดียวและส่งไปยังหน้าต่างที่ตั้งตำแหน่งในขั้นตอน $ Digest ของขอบเขต เนื่องจากการเปลี่ยนแปลงในหลายสถานะของตำแหน่ง $ จะถูกรวมเข้ากับการเปลี่ยนแปลงครั้งเดียวในเบราว์เซอร์วิธีการแทนที่ () เรียกว่าเพียงครั้งเดียวเพื่อให้การกระทำทั้งหมดมีเพียงการแทนที่เพียงครั้งเดียว () ซึ่งจะไม่ทำให้เบราว์เซอร์สร้างประวัติเพิ่มเติม เมื่อเบราว์เซอร์ได้รับการอัปเดตบริการ $ ตำแหน่งจะรีเซ็ตบิตธงผ่านวิธีการแทนที่ () และการเปลี่ยนแปลงในอนาคตจะสร้างประวัติใหม่เว้นแต่จะแทนที่ () จะถูกเรียกอีกครั้ง
การเข้ารหัส setter และอักขระ
เราสามารถส่งอักขระพิเศษไปยังบริการ $ ตำแหน่งและบริการจะเข้ารหัสโดยอัตโนมัติตามมาตรฐาน RFC3986 เมื่อเราเข้าถึงวิธีการเหล่านี้:
3. โหมด Hashbang และ HTML5
บริการ $ location มีสองโหมดการกำหนดค่าที่สามารถควบคุมรูปแบบ URL ของแถบที่อยู่ของเบราว์เซอร์: โหมด Hashbang (ค่าเริ่มต้น) และโหมด HTML5 ตามการใช้ API ประวัติ HTML5 ในทั้งสองโหมดแอปพลิเคชันใช้ API เดียวกัน บริการ $ location จะร่วมมือกับตัวอย่าง URL ที่ถูกต้องและ API เบราว์เซอร์เพื่อช่วยให้เราทำการเปลี่ยนแปลง URL เบราว์เซอร์และการจัดการประวัติ
1. โหมด Hashbang (โหมดเริ่มต้น)
ในโหมดนี้ $ ตำแหน่งใช้ URL Hashbang ในเบราว์เซอร์ทั้งหมด ตรวจสอบตัวอย่างโค้ดต่อไปนี้เพื่อเรียนรู้เพิ่มเติม:
มัน ('ควรแสดงตัวอย่าง', inject (function ($ locationProvider) {$ locationProvider.html5mode = false; $ locationProvider.hashPrefix = '!';}, ฟังก์ชั่น ($ ตำแหน่ง) {// เปิด http://host.com/base/index.html#! 'http://host.com/base/index.html#!/a'; $ location.search ({a: 'b', c: true}); $ location.absurl () == 'http://host.com/base/index.html#!/new?x=y';รวบรวมแอพของคุณ (อนุญาตให้ Google จัดทำดัชนีแอปของเรา)
หากเราต้องการให้แอปพลิเคชัน AJAX ของเราได้รับการจัดทำดัชนีเราจำเป็นต้องเพิ่มเมตาแท็กพิเศษลงในหัว:
<meta name = "fragment" content = "!" -
การทำเช่นนั้นจะช่วยให้หุ่นยนต์ตัวรวบรวมข้อมูลขอลิงค์ปัจจุบันโดยใช้พารามิเตอร์ _escaped_fragment_ ให้เซิร์ฟเวอร์ของเราทราบหุ่นยนต์ตัวรวบรวมข้อมูลและให้สแน็ปช็อต HTML ที่สอดคล้องกัน สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเทคโนโลยีนี้กรุณาเยี่ยมชม https://developers.google.com/webmasters/ajax-crawling/docs/specification?hl=en-cn
4. โหมด HTML5
ในโหมด HTML5 Getters และ Setters ของบริการ $ location โต้ตอบกับ URL ของเบราว์เซอร์ผ่าน HTML5 ประวัติ API ช่วยให้สามารถใช้เส้นทางปกติและโมดูลค้นหาเพื่อแทนที่โหมด Hashbang หากเบราว์เซอร์บางตัวไม่รองรับ HTML5 ประวัติ API บริการ $ ตำแหน่งจะกลับไปที่โหมดโดยอัตโนมัติโดยใช้ URL HashBang เพื่อให้เรากำจัดข้อกังวลว่ามันไม่ชัดเจนว่าเบราว์เซอร์ที่แสดงแอปพลิเคชันของเรารองรับ API ประวัติโดยใช้บริการ $ ตำแหน่งเป็นตัวเลือกที่ถูกต้องและดีที่สุด
การเปิด URL ปกติในเบราว์เซอร์รุ่นเก่าจะเปลี่ยนเป็น HashBangurl
การเปิด URL Hashbang ในเบราว์เซอร์ที่ทันสมัยจะถูกเขียนใหม่ไปยัง URL ปกติ
1. เข้ากันได้กับเบราว์เซอร์รุ่นเก่า
สำหรับเบราว์เซอร์ที่รองรับ HTML5 History API, $ ตำแหน่งกลับไปยังเส้นทางการเขียนและการค้นหา หากเบราว์เซอร์ไม่รองรับประวัติ API จะมีการแปลงตำแหน่ง $ เพื่อให้ URL Hashbang สิ่งนี้จะถูกแปลงโดยอัตโนมัติโดยบริการ $ location
2. ลิงค์ HTML ใหม่
เมื่อเราใช้โหมดประวัติ API เราต้องการลิงก์ที่แตกต่างกันสำหรับเบราว์เซอร์ที่แตกต่างกัน แต่เราจำเป็นต้องจัดเตรียม URL ปกติเช่น <a href = "/บางอย่าง? foo = bar"> ลิงค์ </a>
เมื่อผู้ใช้คลิกไฮเปอร์ลิงก์นี้:
ในเบราว์เซอร์เก่า URL จะเปลี่ยนเป็น /index.html#!/some?foo=bar
ในเบราว์เซอร์ที่ทันสมัย URL จะเปลี่ยนเป็น /บางอย่าง? foo = bar
ในกรณีต่อไปนี้ลิงค์จะไม่ถูกเขียนใหม่ แต่จะทำให้หน้าเว็บถูกโหลดลงใน URL ที่เกี่ยวข้อง:
ไฮเปอร์ลิงก์ที่มีเป้าหมาย: <a href = "/ext/link? a = b" target = "_ self"> ลิงค์ </a>
ลิงค์สัมบูรณ์ไปยังโดเมนต่าง ๆ : <a href = "http://angularjs.org/"> ลิงค์ </a>
หลังจากตั้งค่าเส้นทางฐานให้ใช้ลิงก์ที่ขึ้นต้นด้วย "/" ไปยังไฮเปอร์ลิงก์ของเส้นทางฐานที่แตกต่างกัน: <a href = "/ไม่ใช่ลิงค์/ลิงก์"> ลิงค์ </a>
3. ฝั่งเซิร์ฟเวอร์
การใช้วิธีนี้ขอการเปลี่ยนเส้นทาง URL บนเซิร์ฟเวอร์เรามักจะต้องเปลี่ยนเส้นทางลิงก์ทั้งหมดของเราไปยังแอปพลิเคชันของเรา (ตัวอย่างเช่น index.html)
4. คลานแอปของคุณ
เหมือนก่อน
5. ลิงก์สัมพัทธ์
ตรวจสอบให้แน่ใจว่าได้ตรวจสอบลิงก์สัมพัทธ์รูปภาพสคริปต์ ฯลฯ เราต้องระบุ URL พื้นฐาน (<base href = " /my-base">) ใน <head> และใช้ URL สัมบูรณ์ (เริ่มต้นด้วย /) ทุกที่ เนื่องจาก URL สัมพัทธ์จะถูกแปลงเป็น URL สัมบูรณ์ตามเส้นทางเริ่มต้นของเอกสาร (มักจะแตกต่างจากรูทของแอปพลิเคชัน) (URL สัมพัทธ์จะได้รับการแก้ไขเป็น URL สัมบูรณ์โดยใช้ URL สัมบูรณ์เริ่มต้นของเอกสารซึ่งมักจะแตกต่างจากรูทของแอปพลิเคชัน)
เราได้รับการสนับสนุนอย่างมากในการเรียกใช้แอปพลิเคชันเชิงมุมที่อนุญาตให้ API ประวัติในรูทเอกสารเพราะสิ่งนี้คำนึงถึงปัญหาการเชื่อมโยงที่สัมพันธ์กันได้ดี
6. การส่งลิงค์ระหว่างเบราว์เซอร์ที่แตกต่างกัน
(สิ่งนี้อธิบายว่าที่อยู่ของสองโหมดสามารถปรับให้เข้ากับเบราว์เซอร์ที่แตกต่างกันแปลงโดยอัตโนมัติและทำซ้ำอีกครั้ง ... )
7. ตัวอย่าง
ในตัวอย่างนี้คุณสามารถเห็นอินสแตนซ์ที่ตั้งอยู่สองแห่งซึ่งทั้งสองอย่างนี้เป็นโหมด HTML5 แต่บนเบราว์เซอร์ที่แตกต่างกันดังนั้นเราจึงสามารถเห็นความแตกต่างระหว่างทั้งสอง บริการ $ location เหล่านี้เชื่อมต่อกับ "เบราว์เซอร์" ปลอมสองตัว แต่ละอินพุตแสดงถึงแถบที่อยู่ของเบราว์เซอร์
โปรดทราบว่าเมื่อเราป้อนที่อยู่ Hashbang ไปยัง "เบราว์เซอร์" เครื่องแรก (หรือที่สอง?) มันจะไม่เขียนใหม่หรือเปลี่ยนเส้นทาง URL อื่นและกระบวนการแปลงนี้จะเกิดขึ้นเมื่อโหลดหน้าใหม่เท่านั้น
<! doctype html> <html ng-app> <head> <base href = ""/> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"/> <title> http-equiv = "x-ua ที่เข้ากันได้"> <style type = "text/css"> .ng-cloak {display: none; } </style> </head> <body> <div ng-non-bindable> <div id = "html5-mode" ng-controller = "html5cntl"> <h4> เบราว์เซอร์ที่มีประวัติ API </h4> {{$ location.protocol ()}} <br> $ location.host () = {{$ location.host ()}} <br> $ location.port () = {{{$ location.port ()}} <br> $ location.path () = {{$ location.path () {{$ location.search ()}} <br> $ location.hash () = {{$ location.hash ()}} <br> <a href = "http://www.host.com/base/first?a=b">/base/base? a = b </a> | <a href = "http://www.host.com/base/sec/ond?flag#hash"> sec/ond? Flag#hash </a> | <a href = "/อื่น ๆ/อื่น ๆ ? ค้นหา"> ภายนอก </a> </div> <div id = "hashbang-mode" ng-controller = "hashbangcntl"> <h4> เบราว์เซอร์ที่ไม่มีประวัติ API </h4> <div ng-adddress-bar {{$ location.protocol ()}} <br> $ location.host () = {{$ location.host ()}} <br> $ location.port () = {{{$ location.port ()}} <br> $ location.path () = {{$ location.path () {{$ location.search ()}} <br> $ location.hash () = {{$ location.hash ()}} <br> <a href = "http://www.host.com/base/first?a=b">/base/base? a = b </a> | <a href = "http://www.host.com/base/sec/ond?flag#hash"> sec/ond? Flag#hash </a> | <a href = "/อื่น ๆ/อื่น ๆ ? ค้นหา"> ภายนอก </a> </div> </div> <script src = "../ angular.js" type = "text/javascript"> </script> <script type = "text/javascript" - this.url = function () {return initurl; - this.defer = function (fn, delay) {settimeout (function () {fn ();}, การหน่วงเวลา || 0); - this.basehref = function () {return basehref; - สิ่งนี้จะแจ้งให้ทราบว่าเมื่อใดก็ตาม } var browsers = {html5: New FakeBrowser ('http://www.host.com/base/path?a=b#h', '/base/index.html'), hashbang: New FakeBrowser ('http://ww.host.com/index '/base/index.html')}; ฟังก์ชั่น html5cntl ($ scope, $ ตำแหน่ง) {$ scope. $ location = $ ตำแหน่ง; } ฟังก์ชั่น hashbangcntl ($ scope, $ ตำแหน่ง) {$ scope. $ location = $ ตำแหน่ง; } function initenv (ชื่อ) {var root = angular.element (document.getElementById (ชื่อ + '-mode')); Angular.bootstrap (root, [function ($ compileProvider, $ locationProvider, $ prost) {debugger; $ locationprovider.html5mode (จริง) .hashprefix ('!'); $ provel.value ('$ browser', browsers [name]; {ประวัติ: name == 'html5'}); $ compileprovider.directive ('ngaddressbar', ฟังก์ชัน () {return function (ขอบเขต, elm, attrs) {var browser = เบราว์เซอร์ Keydown ', {if! delay) {delay = settimeout (Fireurlchange, 250); - root.bind ('คลิก', ฟังก์ชั่น (e) {e.stoppropagation ();}); } initenv ('html5'); initenv ('hashbang'); </script> </body> </html>V. คำแนะนำเพิ่มเติม
1. การนำทางโหลดหน้าใหม่
บริการ $ location ช่วยให้เราสามารถเปลี่ยน URL เท่านั้น ไม่อนุญาตให้เราโหลดหน้าใหม่ เมื่อเราต้องการเปลี่ยน URL และโหลดหน้าใหม่หรือข้ามไปยังหน้าอื่น ๆ เราต้องใช้จุดระดับต่ำเพื่อรับ API, $ window.location.href
2. การใช้สถานที่ $ นอกวงจรชีวิตขอบเขต
$ ตำแหน่งรู้ขอบเขตชีวิตของ Angular เมื่อ URL ของเบราว์เซอร์เปลี่ยนไปจะอัปเดตตำแหน่ง $ และการโทรไปที่ $ Apply ดังนั้น $ ทั้งหมด Watcher และ $ Observer จะได้รับแจ้ง เมื่อเราแก้ไขตำแหน่ง $ ในขั้นตอน $ Digest จะไม่มีปัญหา $ สถานที่จะเผยแพร่การดัดแปลงนี้ไปยังเบราว์เซอร์และแจ้งให้ผู้เฝ้าดู $ ทั้งหมดและ $ Observer ทั้งหมด เมื่อเราต้องการเปลี่ยนตำแหน่ง $ นอก Angular (เช่นในเหตุการณ์ DOM หรือในการทดสอบ) เราต้องโทรไปที่ $ จะใช้เพื่อเผยแพร่การเปลี่ยนแปลงนี้
3. $ location.path () และ! หรือ / คำนำหน้า
เส้นทางสามารถเริ่มต้นโดยตรงด้วย "/"; Setter $ location.path () จะถูกเติมโดยอัตโนมัติเมื่อค่าไม่เริ่มต้นด้วย "/"
สังเกต "!" คำนำหน้าในโหมด Hashbang ไม่ได้อยู่ในส่วนหนึ่งของ $ location.path () มันเป็นแค่ hashprefix
6. การทดสอบด้วยบริการ $ location
เมื่อใช้บริการ $ location ในการทดสอบมันอยู่นอกวงจรชีวิตขอบเขตเชิงมุม ซึ่งหมายความว่าเราต้องรับผิดชอบในการโทรหาขอบเขต APPY ()
อธิบาย ('ServiceUnderTest', function () {ก่อนหน้า (โมดูล (ฟังก์ชั่น ($ ให้) {$ proty.factory ('ServiceUnderTest', ฟังก์ชั่น ($ ตำแหน่ง) {// สิ่งที่มันทำ ... });}); มัน ('ควร ... บริการควรทำ ... }));});7. การย้ายจาก AngularJS ก่อนหน้านี้
ในช่วงต้นเชิงมุม, $ ตำแหน่งที่ใช้ hashpath หรือ hashsearch เพื่อประมวลผลเส้นทางและวิธีการค้นหา ในรุ่นนี้เมื่อจำเป็นบริการ $ ตำแหน่งจะประมวลผลเส้นทางและวิธีการค้นหาจากนั้นใช้ข้อมูลที่ได้รับเพื่อสร้าง URL hashbang (ตัวอย่างเช่น http://server.com/#!/path?search=a)
8. การเชื่อมโยงสองทางกับตำแหน่ง $
ปัจจุบันคอมไพเลอร์เชิงมุมไม่รองรับวิธีการสองทาง (https://github.com/angular/angular.js/issues/404) หากเราต้องการใช้การเชื่อมโยงสองทางกับวัตถุที่อยู่ที่ $ (โดยใช้ NGMODEL Directive ในอินพุต) เราจำเป็นต้องระบุคุณสมบัติโมเดลเพิ่มเติม (ตัวอย่างเช่น: LocationPath) และเพิ่มสอง $ นาฬิกาเพื่อฟังการอัปเดต $ ในทั้งสองทิศทางตัวอย่างเช่น:
<input type = "text" ng-model = "locationPath" />
// js - คอนโทรลเลอร์ $ scope. $ watch ('LocationPath', ฟังก์ชั่น (เส้นทาง) {$ location.path (เส้นทาง);); $ scope. $ watch ('$ location.path ()', ฟังก์ชั่น (เส้นทาง) {scope.locationpath = path;});ข้างต้นคือข้อมูลเกี่ยวกับ AngularJS โดยใช้ตำแหน่ง $ เราจะยังคงเพิ่มข้อมูลที่เกี่ยวข้องในอนาคต ขอบคุณสำหรับการสนับสนุนเว็บไซต์นี้!