- vừa được xem lúc

[Declarative Programming + Elm] Bài 16 - URL Parser Module

0 0 9

Người đăng: Semi Dev

Theo Viblo Asia

Để xây dựng một Web App thực sự thì hiển nhiên là chúng ta sẽ muốn hiển thị những nội dung khác nhau tương ứng với các Url khác nhau, không chỉ đối với những liên kết tĩnh như trang chủ / hay trang giới thiệu /about mà còn những liên kết có chứa các tham số truy vấn ví dụ như /search?q=seiza.

Để tạo ra logic điều hướng dựa trên các liên kết có chứa tham số truy vấn như vậy thì chúng ta cần học cách sử dụng thêm một số công cụ được cung cấp bởi package elm/url mà chúng ta đã cài đặt trước đó. Và ở đây, chúng ta sẽ tiếp tục xem xét ví dụ được Elm đẳng tải trong loạt bài viết hướng dẫn trên trang web chính thức của họ.

Ví dụ 1

Giả sử chúng ta đang có một website và các path được liệt kê dưới đây đều hợp lệ.

  • /topic/architecture
  • /topic/painting
  • /topic/sculpture
  • /blog/42
  • /blog/123
  • /blog/451
  • /user/tom
  • /user/sue
  • /user/sue/comment/11
  • /user/sue/comment/51

Như vậy là chúng ta đang có các trang hạng mục topic, các trang bài viết blog, các trang thông tin người dùng user, và phương thức để tìm kiếm bình luận của người dùng. Và bây giờ chúng ta có code ví dụ sử dụng module Url.Parser để viết một chương trình phân tích đường dẫn Url như sau:

type Route = Topic String | Blog Int | User String | Comment String Int routeParser : Parser (Route -> a) a
routeParser = oneOf [ map Topic (s "topic" </> string) , map Blog (s "blog" </> int) , map User (s "user" </> string) , map Comment (s "user" </> string </> s "comment" </> int) ]

Chúng ta đang có hàm routeParser không có tham số đầu vào và sẽ trả về một trình khởi tạo Parser với thông tin định kiểu cụ thể là Parser (Route -> a) a. Tất cả các hàm hỗ trợ s, </>, string, int, đều được import từ module Url.Parser và được thiết kế để có cú pháp sử dụng ở bề mặt code tương ứng với định dạng của path mà chúng ta cần tách lấy các tham số truy vấn.

Ok, như vậy là với cú pháp biểu thị dạng đường dẫn path cần tách lấy các tham số như trên thì chúng ta có:

  • Các chuỗi tĩnh trong path được mô tả bởi các lời gọi hàm s
  • Các lời gọi hàm </> tương ứng với các dấu xổ nghiêng / trong path
  • Và các hàm string, int, mô tả vị trí tách lấy các tham số truy vấn và kiểu dữ liệu trả về

Và đây là kết quả hoạt động của trình Parser được trả về bởi hàm routeParser.

-- /topic/pottery ==> Just (Topic "pottery")
-- /topic/collage ==> Just (Topic "collage")
-- /topic/ ==> Nothing -- /blog/42 ==> Just (Blog 42)
-- /blog/123 ==> Just (Blog 123)
-- /blog/mosaic ==> Nothing -- /user/tom/ ==> Just (User "tom")
-- /user/sue/ ==> Just (User "sue")
-- /user/ ==> Nothing -- /user/bob/comment/42 ==> Just (Comment "bob" 42)
-- /user/sam/comment/35 ==> Just (Comment "sam" 35)
-- /user/sam/comment/ ==> Nothing

Việc đọc code định nghĩa của các hàm đã sử dụng trong module Url.Parser cũng quan trọng nhưng không hẳn là cần thiết ở thời điểm khởi đầu, bởi chúng ta đã nhìn thấy cú pháp sử dụng ở dạng mô tả trực quan rất declarative, dễ hiểu và dễ áp dụng theo mà không cần phải đọc hiểu trình tự hoạt động cụ thể của các lời gọi hàm ở đây.

Ví dụ 2

Bây giờ là một trường hợp ví dụ khác khi chúng ta đang có một trang blog cá nhân với các đường dẫn hợp lệ như sau:

  • /blog/12/the-history-of-chairs
  • /blog/13/the-endless-september
  • /blog/14/whale-facts
  • /blog/
  • /blog?q=whales
  • /blog?q=seiza

Trong trường hợp này, chúng ta đang có các trang bài viết /blog/number/ và các trang kết quả tìm kiếm /blog?q=... với tham số truy vấn ở khóa q=. Để tách lấy tham số các thám số truy vấn tùy chọn ở vị trí khóa q= thì chúng ta cần sử dụng thêm module Url.Parser.Query.

import Url.Parser exposing (Parser, (</>), (<?>), int, map, oneOf, s, string)
import Url.Parser.Query as Query type Route = BlogPost Int String | BlogQuery (Maybe String) routeParser : Parser (Route -> a) a
routeParser = oneOf [ map BlogPost (s "blog" </> int </> string) , map BlogQuery (s "blog" <?> Query.string "q") ]

Cú pháp áp dụng trong trường hợp này cũng hoàn toàn dễ nhìn thấy dạng của path được mô tả trong code. Và đây là kết quả hoạt động của trình Parser được trả về bởi hàm routeParser.

`/blog/12/the-history-of-chairs` ==> Just (BlogPost 12 "the-history-of-chairs")
`/blog/13/the-endless-september` ==> Just (BlogPost 13 "the-endless-september")
`/blog/14/whale-facts` ==> Just (BlogPost 14 "whale-facts")
`/blog/` ==> Just (BlogQuery Nothing)
`/blog?q=whales` ==> Just (BlogQuery (Just "whales"))
`/blog?q=seiza` ==> Just (BlogQuery (Just "seiza"))

Ví dụ 3

Và ví dụ cuối cùng là chúng ta có một website dạng trang tài liệu tổng hợp với các đường dẫn hợp lệ như sau:

  • /Basics
  • /Maybe
  • /List
  • /List#map
  • /List#filter
  • /List#foldl

Trong trường hợp này, chúng ta đang có các đường dẫn chứa các tên định danh id của một phần tử HTML nào đó. Và để tách lấy các id này thì chúng ta sẽ cần sử dụng thêm hàm fragment trong module Url.Parser.

type alias Docs = (String, Maybe String) docsParser : Parser (Docs -> a) a
docsParser = map Tuple.pair (string </> fragment identity)

Như vậy là chúng ta có các lời gọi hàm </> fragment identity để bắt đầu tách lấy #id ở đoạn cuối cùng của path, có phần hơi đặc biệt. Tuy nhiên chúng ta cũng có thể đọc theo cách đơn giản, </> fragment là ký hiệu #, và identity là vị trí của chuỗi id cần tách lấy trong path. Và đây là kết quả hoạt động tương ứng.

-- /Basics ==> Just ("Basics", Nothing)
-- /Maybe ==> Just ("Maybe", Nothing)
-- /List ==> Just ("List", Nothing)
-- /List#map ==> Just ("List", Just ("map"))
-- /List#filter ==> Just ("List", Just ("filter"))
-- /List#foldl ==> Just ("List", Just ("foldl"))

Như vậy là chúng ta cũng đã biết thêm cách sử dụng module Url để tách lấy các tham số truy vấn trong path để có thể sử dụng cho logic xử lý trong hàm update của Browse.application.

Sau đó thì update sẽ tạo ra một bản ghi model mới tương ứng với thông tin truy vấn được để view có thể điều chỉnh giao diện hiển thị của trang đơn cho phù hợp với yêu cầu của người dùng. Phần còn lại của câu chuyện lúc này là chúng ta chưa có cách thức để thay đổi nội dung của phần tử <head> bởi Elm không có module nào hỗ trợ.

(chưa đăng tải) [Declarative Programming + Elm] Bài 17 - JavaScript Inter-Operation

Bình luận

Bài viết tương tự

- vừa được xem lúc

Closure trong Javascript - Phần 2: Định nghĩa và cách dùng

Các bạn có thể đọc qua phần 1 ở đây. Để mọi người không quên, mình xin tóm tắt gọn lại khái niệm lexical environment:.

0 0 51

- vừa được xem lúc

Var vs let vs const? Các cách khai báo biến và hằng trong Javascript

Dạo này mình tập tành học Javascript, thấy có 2 cách khai báo biến khác nhau nên đã tìm tòi sự khác biệt. Nay xin đăng lên đây để mọi người đọc xong hy vọng phân biệt được giữa let và var, và sau đó là khai báo hằng bằng const.

0 0 31

- vừa được xem lúc

VueJS: Tính năng Mixins

Chào mọi người, hôm nay mình sẽ viết về Mixins và 1 số vấn đề trong sử dụng Mixins hay ho mà mình gặp trong dự án thực. Trích dẫn từ trang chủ của VueJS:.

0 0 27

- vừa được xem lúc

Asset Pipeline là cái chi chi?

Asset Pipeline. Asset pipeline là cái chi chi. . Giải thích:.

0 0 47

- vừa được xem lúc

Tạo data table web app lấy dữ liệu từ Google Sheets sử dụng Apps Script

Google Sheets là công cụ tuyệt vời để lưu trữ bảng tính trực tuyến, bạn có thể truy cập bảng tính bất kỳ lúc nào ở bất kỳ đâu và luôn sẵn sàng để chia sẻ với người khác. Bài này gồm 2 phần.

0 0 266

- vừa được xem lúc

Học Deep Learning trên Coursera miễn phí

Bạn muốn bắt đầu với Deep Learning nhưng không biết bắt đầu từ đâu? Bạn muốn có một công việc ở mức fresher về Deep Learning? Bạn muốn khoe bạn bè về kiến thức Deep Learning của mình. Bắt đầu từ đâu.

0 0 35