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

[Declarative Programming + Elm] Bài 15 - Navigation & URL Parser

0 0 25

Người đăng: Semi Art

Theo Viblo Asia

Trong bài viết này, chúng ta sẽ xem xét một ví dụ đơn giản mà Elm đưa ra về việc xử lý yêu cầu điều hướng giữa các trang nội dung đơn khi người dùng nhấn vào một liên kết bất kỳ trong SPA. Để thực hiện ví dụ này, chúng ta sẽ cần cài đặt thêm một package hỗ trợ.

cd Documents && cd learn-elm
elm install elm/url
elm reactor

Navigation

Đầu tiên vẫn là chương trình main với đầy đủ các yếu tố kiến trúc theo yêu cầu tham số đầu vào của Browser.application.

module Main exposing (main) import Browser exposing (..)
import Browser.Navigation as Navigation exposing (Key)
import Html exposing (..)
import Html.Attributes as Attributes exposing (..)
import Url exposing (..) -- main - - - - - - - - - - - - - - - - - - - - - - - - - - - type alias SPA = { init : () -> Url -> Key -> ( Model, Cmd Msg ) , view : Model -> Document Msg , update : Msg -> Model -> ( Model, Cmd Msg ) , subscriptions : Model -> Sub Msg , onUrlRequest : UrlRequest -> Msg , onUrlChange : Url -> Msg } main : Program () Model Msg
main = Browser.application ( SPA init view update subscriptions onUrlRequest onUrlChange )

Chúng ta sẽ có một kiến trúc HTML rấ đơn giản bao gồm một danh sách <ul> các liên kết điều hướng và một <div> hiển thị nội dung của trang đơn tương ứng với mỗi liên kết. Nội dung hiển thị ở đây sẽ chỉ đơn giản là đường dẫn đầy đủ của trang đơn cần hiển thị. Do đó nên initview cũng khá đơn giản.

-- init - - - - - - - - - - - - - - - - - - - - - - - - - - - type alias Model = { key : Key , url : Url } init : () -> Url -> Key -> ( Model, Cmd Msg )
init _ url key = ( Model key url, Cmd.none ) -- view - - - - - - - - - - - - - - - - - - - - - - - - - - - view : Model -> Document Msg
view model = { title = "URL & Navigation" , body = [ ul [] [ li [] [ link "/home" ] , li [] [ link "/profile" ] , li [] [ link "/reviews/the-century-of-the-self" ] , li [] [ link "/reviews/public-opinion" ] , li [] [ link "/reviews/shah-of-shahs" ] ] , div [] [ h1 [] [ text ( Url.toString model.url ) ] ] ] } link : String -> Html msg
link path = a [ href path ] [ text path ]

Ở đây cả initview đều không có điểm nào gửi Msg tới trình điều khiển chính Program. Tuy nhiên có một yếu tố mới đó là kiểu Key được sử dụng tại init. Giá trị này được sử dụng để đảm bảo các sub-program của module Navigation bao gồm pushUrl, replaceUrl, back, và forward sẽ chỉ có hiệu lực nếu được cung cấp đúng key đã khởi tạo khi trang web mới được tải về trình duyệt.

Các trường hợp xử lý tại trình update lúc này sẽ bao gồm:

  • Người dùng nhập địa chỉ mới vào thanh địa chỉ Address Bar của trình duyệt web.
  • Người dùng click chuột vào một liên kết trong trang web:
    • Liên kết trỏ tới một trang đơn cùng hệ thống
    • Liên kết trỏ tới một trang web khác
-- update - - - - - - - - - - - - - - - - - - - - - - - - - - - type Msg = LinkClicked UrlRequest | UrlChanged Url update : Msg -> Model -> ( Model, Cmd Msg )
update msg model = case msg of UrlChanged newURL -> ( { model | url = newURL }, Cmd.none ) LinkClicked urlRequest -> case urlRequest of Browser.Internal url -> ( model, Navigation.pushUrl model.key ( Url.toString url ) ) Browser.External href -> ( model, Navigation.load href )

Và các yếu tố kiến trúc còn lại...

-- subscriptions - - - - - - - - - - - - - - - - - - - - - - - - - - - subscriptions : Model -> Sub Msg
subscriptions _ = Sub.none -- onUrlRequest - - - - - - - - - - - - - - - - - - - - - - - - - - - onUrlRequest : UrlRequest -> Msg
onUrlRequest = LinkClicked -- onUrlChange - - - - - - - - - - - - - - - - - - - - - - - - - - - onUrlChange : Url -> Msg
onUrlChange = UrlChanged

Logic điều hướng của SPA lúc này khá dễ theo dõi với onUrlChangeonUrlRequest. Bởi vì sau cùng thì khi liên kết thay đổi, chúng ta cũng chỉ có các khả năng này:

  • Hoặc là người dùng nhập một địa chỉ mới vào thanh address bar, thì onUrlChange sẽ được kích hoạt và UrlChanged được gửi tới trình update.
  • Hoặc là người dùng click chuột vào một liên kết trong trang web, thì onUrlRequest sẽ được kích hoạt và LinkClicked được gửi tới trình update.

http://localhost:8000/src/Main.elm

Trường hợp duy nhất mà update cần phải tạo ra bản ghi Model với url mới đó là khi người dùng click chuột vào một liên kết trỏ tới trang đơn nội dung trong cùng hệ thống. Đó là khi bản ghi Model mới được gửi tới view và chúng ta sẽ có giao diện của trang web được thay đổi thành giao diện trang đơn phù hợp với yêu cầu.

Và hiển nhiên, trong trường hợp này thì trình duyệt web sẽ không cần phải tải lại toàn bộ văn bản HTML và người dùng sẽ không phải tạm thời nhìn thấy một cửa sổ trống.

URL Parser

Trên thực tế thì sau thao tác điều hướng căn bản, chúng ta sẽ phải tìm hiểu thêm cách thức để phân tích đường dẫn yêu cầu Request Url trong trường hợp người dùng nhấn vào một liên kết trỏ tới một trang đơn cùng hệ thống.

Tuy nhiên việc tìm hiểu các công cụ xử lý nhóm tác vụ này sẽ yêu cầu sử dụng các sub-program được gọi là Higher Order Functions mà mình đã xác định là để dành cho Sub-Series tiếp theo. Và vì vậy nên câu chuyện SPA của chúng ta sẽ cần lui lại một chút cho đến khi Higher Order Functions và một số khái niệm liên quan được giới thiệu xong ở Sub-Series mới:

(chưa đăng tải) [Functional Programming + Haskell] Bài 1 - ...

Song song với đó thì Sub-Series Declarative vẫn sẽ được tiếp tục trên phương diện là một project nho nhỏ xây dựng một SPA sử dụng Back-End là Wikipedia API.

(chưa đăng tải) [Declarative Programming + Elm] Bài 16 - ...

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 52

- 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 32

- 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 28

- 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 48

- 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 36