2013-05-31 35 views
5

Tôi đang xây dựng một trang web đơn giản trong giao diện người dùng web Dart. Mỗi trang có một tiêu đề (với điều hướng trang web) và một chân trang. Tôi đã sử dụng các thành phần cho đầu trang và chân trang và mỗi trang trông giống như sau:Biên soạn các thành phần giao diện người dùng web thành HTML

<!DOCTYPE html> 
<html> 
<head> 
    <title>Test</title> 

    <link rel="import" href="header.html"> 
    <link rel="import" href="footer.html"> 
</head> 

<body> 
    <header-component></header-component> 

    Page content... 

    <footer-component></footer-component> 
</body> 
</html> 

Điều này hoạt động tốt nhưng các thành phần không được chèn vào HTML nhưng được nạp động từ Dart (hoặc JavaScript) mã. Có cách nào để trình biên dịch Web UI chèn đầu trang và chân trang vào chính tệp HTML để chúng hiển thị với các công cụ tìm kiếm và cho người dùng đã tắt JavaScript không?

Trả lời

2

Không có cách nào trực tiếp để thực hiện việc này.

Đây thường là nhiệm vụ phía máy chủ: máy chủ xử lý để tạo HTML bắt buộc.

Các thành phần web là tất cả về phía khách hàng, vì vậy chúng hoạt động trên những gì đã được phân phối cho trình duyệt.

Tuy nhiên, build.dart tập lệnh được thực thi mỗi khi một tệp trong dự án của bạn thay đổi để bạn có thể mở rộng tập lệnh để có được những gì bạn muốn. Tôi không nghĩ đây là một cách tiếp cận tốt, nhưng nó giải quyết vấn đề của bạn.

Đầu tiên thêm placeholder sau vào tập tin mục tiêu html (trong trường hợp của tôi web/webuitest.html):

<header></header> 

Bây giờ thêm một file header.html để dự án của bạn với một số nội dung:

THIS IS A HEADER 

Bây giờ mở rộng build.dart tập lệnh để nó sẽ kiểm tra xem header.html đã được sửa đổi hay chưa và nếu có, nó sẽ cập nhật webuitest.html:

// if build.dart arguments contain header.html in the list of changed files 
if (new Options().arguments.contains('--changed=web/header.html')) { 
    // read the target file 
    var content = new File('web/webuitest.html').readAsStringSync(); 
    // read the header 
    var hdr = new File('web/header.html').readAsStringSync(); 
    // now replace the placeholder with the header 
    // NOTE: use (.|[\r\n])* to match the newline, as multiLine switch doesn't work as I expect 
    content = content.replaceAll(
     new RegExp("<header>(.|[\r\n])*</header>", multiLine:true), 
     '<header>${hdr}</header>'); 
    // rewrite the target file with modified content 
    new File('web/webuitest.html').writeAsStringSync(content); 
    } 

Một hệ quả của phương pháp này là viết lại mục tiêu sẽ kích hoạt build.dart một lần nữa, vì vậy tệp đầu ra sẽ được tạo hai lần, nhưng đó không phải là vấn đề lớn.

Tất nhiên, điều này có thể được thực hiện tốt hơn nhiều, và ai đó thậm chí có thể quấn nó vào một thư viện.

+0

Không phải là rất đẹp, nhưng nó hoạt động. Cảm ơn. – JJJ

+0

đúng, nó xấu xí như địa ngục :) Trên thực tế, tôi nghĩ về việc xây dựng một thư viện cho điều này, nhưng quyết định không, vì nó không phải là một cái gì đó tôi muốn nhìn thấy thường xuyên. –

+0

@Juhana, BTW, ban đầu tôi nghĩ về việc viết lại các tệp trong thư mục 'out', nhưng trình soạn thảo cũng giám sát các tệp này (tôi nghĩ có một lỗi được gửi cho điều này) để nó kích hoạt một vòng lặp xây dựng lại vô hạn –

2

Hiện tại, không, không thể. Những gì bạn muốn là hiển thị phía máy chủ của các mẫu đó để bạn có thể phân phát chúng trực tiếp cho khách hàng khi họ yêu cầu các trang của bạn (bao gồm cả trình thu thập thông tin tìm kiếm).

Bạn có thể muốn theo dõi tuy nhiên vấn đề này: https://github.com/dart-lang/web-ui/issues/107?source=c

Khi nó đã hoàn thành mọi thứ đang tìm kiếm tốt hơn.

+0

tốt, không có lý do tại sao 'build.dart' không thể được mở rộng để chỉ viết lại một tệp khi một tệp khác thay đổi. xấu xí, chắc chắn, nhưng không thực sự phức tạp –

+0

Tôi không thực sự cần hiển thị phía máy chủ, chỉ cần "chèn tệp ngay tại đây vì nó trước khi hiển thị trang này", nhưng tôi cho rằng tính năng đó cũng sẽ bao gồm nó. – JJJ

+0

Ồ, chỉ cần nhớ rằng giải pháp của @ Zdeslav không quy mô chút nào :) –

Các vấn đề liên quan