AJAXおよびすべて、すべて、すべて
前のシリーズでは、jQueryを使用して簡単なGrailsアプリケーションを作成し、GrailsでjQueryを使用することは可能であり、必要であると判断しました。 そのような束でできるもっと深刻なことを議論します。
ますます多くのサイトがAJAXおよび部分的なページ更新を使用していることは、驚くほどの量です。 特に、「詰められた」AJAXリンクはページ上の内部ナビゲーションに使用でき、いくつかのタブを切り替えます。 これはいいから
A)サーバーから抽出する必要があるデータが少なくなります-ページの必要な部分のみと
B) Webページは単純に巨大なCSSおよびJavaScriptファイルをロードすることが多く、これらはAJAX更新中にリロードできません。
そのため、スクリプトアプリケーションの構築は非常に一般的です。1つの大きな「スタート」ページですべてのJavaScriptコードとCSSをロードし、小さな「内部」ファンクションブロックをAJAXでロードします。 これには多くの問題があります。
- AJAXアクションの結果として、ページの内部状態はブラウザーのアドレスバーに反映されません。
- 結果として、内部ページはブックマークできず、「友人へのリンクを送信」できません。
- ブラウザの戻る/進むナビゲーションは機能しません。 AJAXリンクはブラウザの履歴には含まれません。
ただし、大規模なサイトでは、何らかの「ハッカー」ソリューションが見つかっているため、GrailsとjQueryで独自の類似物を少し検討して記述します。
アンカーナビゲーション
実際には、アンカーのみを変更すると、ページをリロードせずにブラウザのアドレスバーを変更できる、ということです。 バーに続くアドレスバーの最後の部分は
#
です。 ブラウザーはページ内でこの遷移を認識し、ページ上の目的のアンカーが存在しない状況を静かに無視し、アドレスと
履歴を更新するだけです。 これがまさに必要なものです。 ページの状態をアンカー内に保存すると、ブックマークを介してページに戻ることができ、戻る/進むトランジション(!)を使用できます。 この場合、ページのベースURLは変更されず、ページはリロードされません。
そのようなソリューションの実装の例に目を向ける必要はありません。 このスキームは、Facebook、Gmail、Google Picasaウェブアルバムで使用されています。このかなりの部分はodnoklassniki.ruで見ることができます。 Google Web Toolkitライブラリは、アンカーナビゲーションに完全に基づいています。
Gmailでは、レターへの直接リンクを取得でき、リンクはブックマーク可能になります。 リンクは次のようになります。
mail.google.com/mail/?shva=1 #inbox/12c5f14c01a5473c
12c5f14c01a5473c
が手紙の内部IDのようなものであるという
12c5f14c01a5473c
はありません。
アプリケーションを書く
このアプローチの実装について考えてみましょう。 アドレスバーの変更は次のとおりです。
document.location.hash = '#myAnchor';
(または直接リンクから
<a href="#myAnchor">My Link</a>
)
興味をそそる
my-appという名前のGrailsアプリケーションの作成を始めましょう。ナビゲーションは完全にAJAXに基づいています。 アプリケーションには3つのタブがあります。
外見は通常のページのように見えますが、完全なリロードなしでページの内部のみが更新されるようにする必要があります。
最初に、次の形式のSiteMeshレイアウトを描画します。
grails-app/views/layouts/main.gsp
<html> <head> <title><g:layoutTitle default="Grails" /></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="${resource(dir:'css',file:'main.css')}" /> <g:layoutHead /> <g:javascript library="jquery"/> <g:javascript library="application" /> </head> <body> ... %{-- --}% <div class="navbar"> <div class="navitem"> <a href="#do/receipts" class="navlink"></a> <div class="spinner" /> </div> <div class="navitem"> <a href="#do/buy" class="navlink"> </a> <div class="spinner" /> </div> <div class="navitem"> <a href="#do/feedback" class="navlink"></a> <div class="spinner" /> </div> </div> %{-- --}% <div id="pageContent"> <g:layoutBody /> </div> ... </body> </html>
ここにはまだ驚きはありません。 ご覧のとおり、リンクは通常のアンカーリンクと変わりません。 彼らはどのように機能しますか? これを行うには、jQueryでそのようなコードを記述します。
web-app/js/application.js
ここのすべては非常に簡単です。ページの現在の状態をJavaScript変数
currentStateに保存します。 リンクをクリックすると、AJAX経由で内部ページが読み込まれ、AJAX呼び出しの結果が
div#pageContentに保存されます。 この場合、読み込まれたページのURLは、ページのベースアドレスにアンカーパスを追加することで形成されます。
/my-app/#do/receipts => /my-app/do/receipts
この単純なルールは、リンクが何をするかをすぐに理解するのに役立ちます。 リンクを「現在」として認識するために、
disabled
クラスをそれに割り当てます。 CSS(これは提供しません)では、このクラスが異なる色で表示されるため、どのリンクが現在(訪問済み)であるかがわかります。
サーバー側
サーバースタッフィングを作成するといいでしょう。 3つのリンクすべてを処理する単純なコントローラーを作成しました。
grails-app/controllers/DoSomethingController.groovy
class DoSomethingController { def receipts = { [receipts:[' ', '']] } def buy = { [places:[' ', ' №1']] } def feedback = { [feedback:['',' ',' , !']] } }
そして彼のために3つの簡単なページを作りました そのうちの1つだけを提供します。
grails-app/views/doSomething/receipts.gsp
<%-- --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <meta name="layout" content="main" /> </head> <body> <h1> </h1> <ul> <g:each in="${receipts}" var="receipt"> <li>${receipt.encodeAsHTML()}</li> </g:each> </ul> </body> </html>
ここで
/ do / *リンクにコントローラーを掛けます:
grails-app/conf/UrlMappings.groovy
class UrlMappings { static mappings = { "/do/$action?/$id?" { controller = 'doSomething' } } }
ただし、これでは十分ではありません。 問題があります。クライアントとサーバーの部分を完成させる必要があります。これについては
次の部分で説明します。