最後に、クライアント部分のより詳細な調査を開始します。これは、すでにasp.net mvcとの関連性は低くなっていますが、Web開発には依然として重要です。
TwitterブートストラップとCSS
Twitter Bootstrapはcssフレームワークです。 つまり ブロック、ボタン、ラベル、形状、ナビゲーションを作成するためのツールのセット。 このフレームワークに基づいてアプリケーションを作成します。
詳細はこちら:
http://twitter.github.com/bootstrap/
ブートストラップをインストールします。
Install-Package Twitter.Bootstrap
Jquery.UIを削除します。
Uninstall-Package Jquery.UI.Combined
bootstapをBundleConfigに追加し、そこからjquery.UI(App_Start / BundleConfig.cs)を削除します。
public class BundleConfig { public static void RegisterBundles(BundleCollection bundles) { bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/Scripts/jquery-1.*")); bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( "~/Scripts/modernizr-*")); bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( "~/Scripts/bootstrap*")); bundles.Add(new StyleBundle("~/Content/css") .Include("~/Content/site.css") /* */ .Include("~/Content/bootstrap*")); } }
スタイル設定の優先順位について覚えておくことが重要です。
- インラインブラウザスタイルの優先順位は最も低くなっています。
- ブラウザのカスタムスタイル
- 親要素から継承されたスタイル
- 外部ファイルで指定されている次のCSSスタイル。ここで、ルールを含むファイルが前のファイルを含むファイルの後にある場合、ルールはより重要です(ceteris paribus)。 同じルールがドキュメント内のルールの相対的な位置に適用されます。
- さらに、セレクターを使用するコストがかかります:
- タグの優先度が最も低い:
h1, div, p
- クラスと擬似クラス。 セレクター:
.item { }, :hover { }
- 属性[attr =” value”]。 例:
[type=”checkbox”] {}
- IDが最優先です。 タイプ
#main { }
- タグの優先度が最も低い:
- さらに優先度が高いのは、スタイルタグでスタイルを直接設定することです。
<div style=”width : 203px”></div>
- そして、最優先事項は、それに付随する単語のスタイルです!重要です。
スタイル設定の主な作業は、タグ、クラス(擬似クラス)、および属性の助けを借りて行われます。 style属性でスタイルを設定し、ID属性を使用するのと同様に、
!important
を使用することはお勧めしません。
スタイルを設定するには、cssファイルSite.cssを使用します。 ブートストラップにはすでに基本的なフォームのスタイルがあるため、このブロックを削除してファイル(/Content/Site.css)を残します。
/* Styles for validation helpers -----------------------------------------------------------*/ .field-validation-error { color: #f00; } .field-validation-valid { display: none; } .input-validation-error { border: 1px solid #f00; background-color: #fee; } .validation-summary-errors { font-weight: bold; color: #f00; } .validation-summary-valid { display: none; }
これらは、
Html.ValidationMessage()
、
Html.ValidationSummary()
メソッドでエラーを表示するために使用されるcssスタイルです。
次に、独自のスタイルを作成するルールを定義します。
-
#Main
などのidを介してセレクターを使用することは禁止されています。 これは、ブラウザはこの属性を含むすべての要素を処理しますが、DOMルールではID属性はページ全体で一意でなければならないという事実によるものです。 - 全能性のクラスはSmallCapsタイプを使用します:some-class-name、すべて小文字で、「-」は分離に使用されます。 実際、CSS自体での使用方法。
- 制御のみを目的とするクラス(jsコードでのみ使用)では、lowerCamelCase:someClassName型を分離に使用します。 実際、jsまたはjqueryでコードを記述するための規則と同様に。
- id属性は、タイプUpperCamelCase:
id=”SomeButton”
によって設定されます。 - トップレベルでは
.list, .item, .button, .text, .user, .image, .container, .wrapper
などの汎用クラスを使用しないでください。 - 言葉を複雑にしないでください。
.main-container-left-part-wrapper-list.
ような構造を使用しないでください.main-container-left-part-wrapper-list.
- 必要に応じて、一般的なスタイルを定義します。タイプの一般的な説明で定義します:
.error {color : red }, .left { float : left }.
- 一般から特定へのカスケード説明を使用します。
.list { } .list .item { } <li> .list > .item { }
- そして、複数のクラスを持つタグの場合:
.item.odd { }
のために
<div class="item odd"></div>
- 次のドキュメント構造を使用します
/* - - - - - h1, h2, h3 ... - a - p */ /* : - .error - .field-validation-error . - .show-me { border : 1px solid red; } - .hidden {display : none; } - .relative { position : relative; } */ /* - .popup-window - .popup-window .close - .popup-window .wrapper - .popup-window .header - .error-message - .info-message */ /* - header - .logo - .user-login - nav.main-menu - .main-content - footer */ /* */ /* */ /* */ /* … */
htmlページの構造。
スタイルファイルとjsファイルをメインレイアウトファイル(/Areas/Default/Views/Shared/_Layout.cshtml)に接続します。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> @Styles.Render("~/Content/css") @RenderSection("styles", required: false) @Scripts.Render("~/bundles/modernizr") </head> <body> <div class="navbar navbar-fixed-top"> <div class="navbar-inner"> <div class="container"> <ul class="nav nav-pills pull-right"> @Html.Action("UserLogin", "Home") </ul> </div> </div> </div> @RenderBody() @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) </body> </html>
ここで何が起こっていますか:
- リクエストを取得し、リクエストに応じてルート/デフォルト/ホーム/インデックスを定義します。
- このコントローラー/メソッドには標準ビューがあります-/Home/Index.cshtml
ファイルの先頭で、レイアウトに含まれることが宣言されています。
@{ ViewBag.Title = "LessonProject"; Layout = "~/Areas/Default/Views/Shared/_Layout.cshtml"; }
指定されたレイアウトは、
@RenderBody()
を使用してデータを出力します。 以下を開始します。
![](https://habrastorage.org/storage2/072/655/b11/072655b1163de9eb90791d6fc3899a19.jpg)
ナビゲーションバーの下で体が運転したことがわかります。 このファイルでは、本文(/Content/Site.css)を再定義します。
body { padding-top : 40px !important; }
![](https://habrastorage.org/storage2/713/8f6/e29/7138f6e2945ff76202eec3d889776907.jpg)
はるかに良い。
前にbootstapフォームにクラスを使用したため、登録は次のようになります。
![](https://habrastorage.org/storage2/b61/508/288/b61508288490f8aee9120db277467ac9.jpg)
生年月日の選択を修正して、クラスをHtml .DropDownList()(/Areas/Default/Views/User/Register.cshtml)に追加します。
… <div class="controls"> @Html.DropDownList("BirthdateDay", Model.BirthdateDaySelectList, new { @class = "select-day" }) @Html.DropDownList("BirthdateMonth", Model.BirthdateMonthSelectList, new { @class = "select-month" }) @Html.DropDownList("BirthdateYear", Model.BirthdateYearSelectList, new { @class = "select-year" }) </div>
他のどこかでこの構造を使用して日付を選択する可能性が高いため(事実ではありません)、これは特定の日付(特に登録に関連する)よりも一般的です(/Content/Site.css)
.select-day { width : 50px; } .select-month { width : 90px; } .select-year { width : 70px; }
私たちはチェックします:
![](https://habrastorage.org/storage2/52c/b94/5a1/52cb945a148637c9b1272a7424edc4b4.jpg)
うーい!
Jsファイル構造
jsファイルの説明に渡します。 コードのクライアント部分を操作するためのメインフレームワークとしてjqueryを使用します。 カスタムjsファイルの1つ(/Scripts/common.jsと呼びましょう)は常に呼び出されます。 任意のページに存在する関数を追加します。 他のjsファイルはオプションで呼び出されます。
混乱しないように、/ Scriptsに「admin」と「default」の2つのフォルダーを作成します。
すべてのファイルには、SmallCase形式で書き込まれる一意の名前が付けられ、特定のページ(ほとんど)を参照します。 例:user-register.js-User / Register.cshtmlページに含まれるファイル:
@section scripts { @Scripts.Render("/Scripts/default/user-register.js") }
このセクションは、_Layout.cshtml(/Areas/Default/Views/Shared/_Layout.cshtml)で説明されている場所に表示されます。
… @Scripts.Render("~/bundles/bootstrap") @Scripts.Render("~/bundles/common") @RenderSection("scripts", required: false) </body>
それまでの/App_Start/BundleConfig.csで、説明を追加します。
bundles.Add(new ScriptBundle("~/bundles/common").Include( "~/Scripts/common.js"));
プラグインを除くすべてのカスタムjsクラスの構造は次のとおりです。
function FunctionName() { _this = this; this.init = function () { /* */ $("button").click(function () { var id = $(this).attr("id"); _this.saySomething(id); }); } /* */ this.saySomething = function (id) { alert("-! : " + id); } /* */ function saySomething (id) { alert("-! !: " + id); } } var functionName = null; $().ready(function () { functionName = new FunctionName(); functionName.init(); });
さらに詳しく考えてみましょう。
-
function FunctionName
は、それが配置されているファイルの名前によるUpperCamelCaseスタイル名があります(ファイルcommon.jsおよびuser-register.jsのCommon
およびUserRegister
)。 -
_this = this;
この関数へのリンクを保存して、デリゲート関数内で使用できるようにします -
this.init()
は、処理が初期化される外部(パブリック)関数です。 -
var functionName = null
グローバル変数を作成します。 他のファイルからの使用が可能です。 -
$().ready()
-DOM構造が形成された後に呼び出されます。 JQuery関数。 -
functionName = new FunctionName();
-クラスオブジェクトを作成します。 -
functionName.init();
-初期化する。
リソースファイルの縮小
リソースファイルは時間とともに増大し、一方で、モバイルデバイス向けのモバイルインターネットの開発があり、送信データの量が重要な役割を果たすため、ページの受信の縮小は次のようになります。
- リソースファイルのリクエスト数を減らす
- リソースファイルの削減。
画像、特に小さな画像に対するリクエストの数を減らします。 これは2つの方法で行われます。
?
- スプライトを使用します。 多くのデザイン要素が一度に大きなキャンバスに追加されます。 その後、このキャンバスの一部のオフセットと幅\高さがcssで書き込まれます。
たとえば、画像:
そして、htmlでの使用:
<div class="label label-new sprite"></div>
そしてCSS:
.sprite { background: url("/Media/images/sprite.png"); overflow: hidden; text-indent: -9999px; } .box .label { position: absolute; width: 29px; right: -29px; top: 35px; } .box .label-new { background-position: 0 -15px; height: 119px; }
- 2. base64でエンコードすることにより、CSSで直接非常に小さな画像(アイコン)の広告を使用します。
これを行うために、画像は、たとえばhttp://webcodertools.com/imagetobase64converterの base64に転送されます
次に、タイプ別にcssに追加します。
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAWCAYAAAABxvaqAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+/PlBqi0kAAAAwSURBVHjaYmBgYGBnghFccIIbRPCiEvwggg8LixfOBbN44AaACU4gZvgJIv4DBBgARTIDD2TeBRAAAAAASUVORK5CYII=);
もちろん、コンテンツのアイコンまたは画像を読み込む場合、この方法は適用できません。
cssおよびjsの場合、ファイルの縮小が使用されます。 スペースと区切り文字は削除され、短いローカル変数が使用されます。 ファイルは、jqueryライブラリのように縮小された状態で最初に準備されるか、サーバーで縮小されます。
縮小を有効にするには、Web.configファイルのコンパイルディレクティブを変更する必要があります。
<compilation debug="false" targetFramework="4.5" />
または、/ App_Start / BundleConfig.csに直接含めます。
BundleTable.EnableOptimizations = true;
チェック:
![](https://habrastorage.org/storage2/077/e7c/820/077e7c820ade1cd084c026288d93be80.jpg)
最大527Kの最適化
![](https://habrastorage.org/storage2/894/e36/b15/894e36b15ed7847acaaf2f9d7236fb5f.jpg)
最適化後、251 KB
つまり 2回以上。 実際、この値は、ロードするリソースに応じて、これよりも小さくも大きくもなります。 キャッシュがある場合、ページは追加の作業中に新しいファイルのごく一部のみをダウンロードします。
JQueryのインストール
最初、jqueryはすでにインストールされていますが、フレームワークが更新され、これが頻繁に行われる場合、更新する必要があることは明らかです。
インストールパッケージjQuery
さらに、datepicker、モーダル関数をブートストラップが提供するものから使用するため、以前にJQueryUI( http://jqueryui.com/ )を削除しました。 しかし、JQueryUIには、必要な相互作用機能、つまり ドラッグ可能、ドロップ可能、サイズ変更可能、選択可能、およびソート可能。 それらを選択的にインストールします。
- Install-Package JQuery.UI.Interactionsはjqueryバージョン<1.6を必要とするため、手動でインストールします。
- jqueryui.com/downloadからカスタムダウンロードを選択します
- コアとインタラクションのみを選択します
- 振り回す
- CSSファイルを/コンテンツ/ CSSに転送します
- jsファイルを/スクリプトに転送します(jquery-1.9.1-min.jsは転送する必要はありません)
- BundleConfigで接続します
bundles.Add(new ScriptBundle("~/bundles/jqueryui") .Include("~/Scripts/jquery-ui-1.*")); bundles.Add(new StyleBundle("~/Content/css/jqueryui") .Include("~/Content/jquery-ui-1*"));
- 必要に応じて、ページで発表します。
- できた!
Firebug(Firefox)および開発者ツール(Chrome)
デバッグの利便性のため、FirefoxにはFirebug拡張機能があり、Chromeには組み込みの開発者ツールメカニズムがあります。 開発者ツールの例を見てみましょう。 キーストローク
Shift-Ctrl-I
によって呼び出されます。
勉強しましょう:
- [要素]タブ。
ここで、左側に、要素のDOMツリーが表示されます。 右側にはスタイルがあります。 要素と同様に、スタイルは外出先で編集でき、変更内容は編集されたページのブラウザにすぐに表示されます。 オブジェクトの位置を数ピクセル調整する必要がある場合に非常に便利です。
- リソースタブ
左側にはダウンロードされたすべてのリソースがあり、右側にはそれらを表示できます
- ネットワークタブ
リクエストとこれらのリクエストのタイミングを表示します。 ドキュメント、CSS、JSファイル、異なる色の画像を示します。 ファイルサイズを表示します。
リクエストをクリックすると、たとえば次のようにHTTPリクエストをより詳細に調べることができます。
- [ソース]タブ
メインタブの1つ。 ここで、jsファイルの表示、ブレークポイントの設定、アプリケーションのデバッグを行うことができます。 デバッグ用のVisualStudioのホットキーF9、F10、F11。
- タイムラインタブ
進行中のイベントをブラウザーに表示します。 私はそれを使ったことがない。
- [プロファイル]タブ
プロファイリングの場合、つまり 些細なエラーを見つける。 また、決して使用されません。
- 監査タブ
このタブでは、ページの最適化を確認できます。 つまり ブラウザは、サーバーから送信されるコードの減少、圧縮、余分なcss行の削除につながるアクションを実行することをお勧めします。
- コンソールタブ
同時に、コマンドラインとログ出力ウィンドウの両方。 ログを表示するには、コマンドconsole.log(「メッセージ」)を呼び出す必要があります。
IEでこのコマンドを使用する場合は注意してください。コンソールが開いていない場合、エラーがスローされるためです。
セレクターとバイパス
JQueryは、さまざまなブラウザー用のクライアントコードの開発を支援するツールです。 また、シンプルで論理的なライブラリです。
すべての中心にセレクターがあります。 セレクターを使用すると、DOM(ドキュメントオブジェクトモデル)にある多くの要素を選択し、それらに対してアクションを実行できます:イベントハンドラーの割り当て、場所の変更、属性の変更、選択した要素の削除、選択した要素へのテキストまたはhtmlの追加、オブジェクトの作成。
基本的なルールは次のように書かれています。
$([“ ”][, ])
選択領域が指定されていない場合、ドキュメント全体で検索されます:$(ドキュメント)。 これは、DOM全体のルートノードです。
選択領域が指定されている場合、このノードの境界でのみ検索されます。
セレクタールールは、CSSプロパティを割り当てる原則に従って設定されます。
-
$(“div”)
-すべてのdiv要素を選択します -
$(“.class”)
-既存のクラスクラスを持つすべての要素を選択します -
$(“.class .class1”)
-クラスclassに含まれる既存のクラスclass1を持つすべての要素の選択 -
$(“.class.class1”)
-既存のクラスclass1およびclassを持つすべての要素の選択 -
$(“#Id1”)
-id = Id1の要素(1つ)を選択します -
$(“[type='password']”)
-属性type = 'password'の要素を選択します -
$(“div”, $(“#MainPopup”))
-id = MainPopupの要素に含まれるすべてのdiv要素を選択します -
$(“input[type='checkbox']:checked”)
-チェックされるチェックボックスタイプの入力要素の選択。
要素が見つかったかどうかを確認するには、lengthプロパティを使用できます。
if($("#Id1").length == 0) { alert(" ") }
選択した要素のツリーを上に移動するには、関数.closest()、. parent()、または.parents()を使用できます。
-
parent()
-直接の親(そして彼だけ)を返します -
parents(selector)
-すべての親のセットを返しますparents(selector)
がbodyとhtmlまで指定されていない場合) -
closest(selector)
-セレクタに一致する最も近い要素を返します。要素自体は同じでもかまいません。
イベント
イベントを処理するには、セレクター要素にイベントを割り当てます。 例:
$(".button").click(function () { alert("Button clicked"); });
イベントとは:
- ブラウザイベント
- .error() -ブラウザでスクリプト実行エラーが発生しました
- .resize() -このイベントが割り当てられたコンテナのサイズが変更されました。
- .scroll() -コンテナ内のコンテンツは「スクロール」されました(ここでは、自動スクロールを理解する必要があります。つまり、要素にオーバーフローがある場合:スクロールスタイルとコンテンツがスクロールされます)。
- ドキュメントのダウンロード
- .load() -ロードされたアイテム。 たとえば、srcをimgタグに変更(割り当て)する場合。
- .ready() -DOMドキュメントの読み込みが完了すると呼び出されます。 クラスを初期化するときに常に使用します。
- .uload() -ユーザーがページを閉じたいときに呼び出されます。
- フォームイベント
- .blur() -入力フィールドでフォーカスが失われた場合
- .change() -ドロップダウンリストまたは複数選択リストの選択肢を変更する場合
- .focus() -入力フィールドからフォーカスを取得する場合
- .select() -入力フィールドでテキストまたはテキストの一部を選択するとき
- .submit() -入力フォームを確認するとき
- キーボードイベント
- .focusin() -フォーカスの取得時(アナログフォーカス)
- .focusout() -フォーカスを失ったとき(アナログぼかし)
- .keydown() -キーが押されている間にキーが押されたとき
- .keypress() -キーを押して離すとき
- .keyup() -キーを放したとき
- マウスイベント
- .click() -要素を左クリックしたとき
- .dblclick() -ダブルクリックしたとき
- .hover() -ホバー時
- .mousedown()、. mouseup()、. mouseenter()、. mouseleave()、. mousemove()、. mouseout()、. mouseover() -これらのイベントはすべて、要素に関連する対応するマウスアクションに応答します。
イベントは、新しく作成された要素には適用されませんが、以前に実行されたセレクターの選択に該当することに注意してください。 ただし、2回目の初期化を行うと、イベント処理が既に割り当てられている要素では、このイベントが2回実行されます。
一定のグローバル処理を設定するには、次の構成を使用する必要があります。
$(document).on("click", ".button", function () { alert("Button clicked"); });
属性と値
要素の属性を操作するには、主に次の関数が使用されます。
- .val(value)-value属性の値を設定します。select \ option構成要素に対して-要素を選択します
- .val() -値属性の値、または入力フィールドの場合は値を取得
- .attr(“ attr”) -attr属性の値を取得
- .attr(“ attr”、“ value”) -値valueをattr属性に設定します
- .data(“ id”) -data-id属性の値を取得
- .data(“ id”、“ 20”) -値20をdata-id属性に設定します
- .css(「幅」、「120ピクセル」) -スタイル値の幅を設定します:120ピクセル
- .css(「幅」) -幅の値を取得
- .addClass()/。removeClass()/。toggleClass() -セレクター要素のクラスの追加/削除/切り替え
基本的な操作
要素を操作するには、次の関数を検討してください。
- .show()\。hide() -show \ hide
- .html(htmltext) -innerHtml要素にHTMLテキストを設定します
- .text(テキスト) -要素のテキストにテキストを設定します
- .empty() -セレクター要素をクリアする
- .remove() -セレクター要素を削除する
- .append() -すべての葉の後にhtmlテキストまたはセレクター要素を追加します
- .prepend() -すべてのリーフの前にhtmlテキストまたはセレクター要素を追加します
- .after()/。before() -要素の後に/要素の前にhtmlテキストまたは要素を挿入します
- .appendTo()/。prependTo() -選択された要素を、指定された要素の葉の最後/最初に追加します
アヤックス
メイン関数とメイン関数を考えてみてください(99%のケースで、私はそれだけでした)。
$.ajax({ type: "GET", url: "/ajaxUrl", data: { id: id }, beforeSend: function () { /* - */ }, success: function (data) { /* */ }, error: function () { /* */ } });
他にもパラメータがありますが、場合によってはそれらに頼る価値があります。
パラメーターをさらに詳しく考えてみましょう。
- タイプ。 GETまたはPOST要求。
- url 設定されていない場合、またはデフォルトで設定されている場合、ajaxリクエストは現在のページに送信されます
- データ。 jsonまたはget形式では、これは「id = 1&value = 2」などの同様の文字列です。 フォームのシリアル化を使用できます。
data: $("form").serialize()
チェックボックスの同一値のセットを送信する場合、パラメーターを設定する必要があることに注意してください
traditional : true
beforeSend。 フォームが直接送信される前に生成されるイベント。
成功。 すべてが正常であり、データに実行結果が含まれていることを示すイベント
エラー。 サーバーからの応答が200 OK以外の場合に発生するイベント。
Ajaxログインフォーム。
理論の束、それは練習に移る時間です。 2つ目のログインフォームを作成して、サイトにすばやくログインできるようにします。 [ログイン]をクリックすると、ログインページには移動しません。代わりに、ポップアップウィンドウがポップアップし、すぐにログインを入力するように提案されます。 入力に誤りがある場合、フォームは警告を出します。 / Loginに通常のフォームを残します。必要になります。
Popapフォームは頻繁に使用される可能性があるため、これを標準的な手順と見なします。このようなアドレスでPopupを呼び出します。 ポップアップは常に1つなので、_Layout.cshtml(/Areas/Default/Views/Shared/_Layout.cshtml)にポップアップ用のコンテナーを作成します。
<div id="PopupWrapper"></div>
common.js(/Scripts/common.js)に機能を追加します。
this.showPopup = function (url, callback) { $.ajax({ type: "GET", url: url, success: function (data) { $(".modal-backdrop").remove(); var popupWrapper = $("#PopupWrapper"); popupWrapper.empty(); popupWrapper.html(data); var popup = $(".modal", popupWrapper); $(".modal", popupWrapper).modal(); callback(popup); } }); }
, .modal() – bootstrap.js.
, common.js:
this.init = function () { $("#LoginPopup").click(function () { _this.showPopup("/Login/Ajax", function (modal) { }); }); }
(/Areas/Default/Controller/LoginController.cs):
[HttpGet] public ActionResult Ajax() { return View(new LoginView()); } [HttpPost] public ActionResult Ajax(LoginView loginView) { if (ModelState.IsValid) { var user = Auth.Login(loginView.Email, loginView.Password, loginView.IsPersistent); if (user != null) { return RedirectToAction("Index", "Home"); } ModelState["Password"].Errors.Add(" "); } return View(loginView); }
Index, View – «Ajax», (/Areas/Default/Views/Login/Ajax.cshtml):
![](https://habrastorage.org/storage2/2ce/9b9/26a/2ce9b926a9d91a85780e355233ad495b.jpg)
@model LessonProject.Models.ViewModels.LoginView <div class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h3 id="myModalLabel">Login</h3> </div> <div class="modal-body"> @using (Html.BeginForm("Ajax", "Login", FormMethod.Post, new { @class = "form-horizontal", id = "LoginForm" })) { <fieldset> <legend></legend> <div class="control-group"> <label class="control-label" for="Email"> Email</label> <div class="controls"> @Html.TextBox("Email", Model.Email, new { @class = "input-xlarge" }) <p class="help-block"> Email</p> @Html.ValidationMessage("Email") </div> </div> <div class="control-group"> <label class="control-label" for="Password"> </label> <div class="controls"> @Html.Password("Password", Model.Password, new { @class = "input-xlarge" }) @Html.ValidationMessage("Password") </div> </div> </fieldset> } </div> <div class="modal-footer"> <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button> <button class="btn btn-primary" id="LoginButton">Login</button> </div> </div>
id LoginForm id LoginButton
UserLogin.cshtml (/Areas/Default/Views/Home/UserLogin.cshtml):
<li><span class="btn btn-link" id="LoginPopup"></span></li>
common.js LoginButton, $(“#LoginButton”).click(…) (/Scripts/common.js):
this.init = function () { $("#LoginPopup").click(function () { _this.showPopup("/Login/Ajax", initLoginPopup); }); } … function initLoginPopup(modal) { $("#LoginButton").click(function () { $.ajax({ type: "POST", url: "/Login/Ajax", data : $("#LoginForm").serialize(), success: function (data) { showModalData(data); initLoginPopup(modal); } }); }); } function showModalData(data, callback) { $(".modal-backdrop").remove(); var popupWrapper = $("#PopupWrapper"); popupWrapper.empty(); popupWrapper.html(data); var popup = $(".modal", popupWrapper); $(".modal", popupWrapper).modal(); if (callback != undefined) { callback(popup); } }
再帰呼び出しに注意してください
initLoginPopup
。そして、ここにジレンマがあります。ログインに成功すると、PopupWrapperで新しいページ(またはエラーのあるページ)を読み込む必要はなく、ページを更新するだけです。
これを行うには、トリックを行います。/エリア/デフォルト/ビュー/共有/ _Ok.cshtmlを追加します。その本質はページをリロードすることです。
<script> window.location.reload(); </script>
ログインに成功すると、このビューをロードします。DOMを行のツリーに追加する場合
popupWrapper.html(data);
スクリプトは、他の呼び出しを待たずにページを開始してリロードします。コントローラーを変更します(/Areas/Default/Controllers/LoginController.cs):
var user = Auth.Login(loginView.Email, loginView.Password, loginView.IsPersistent); if (user != null) { return View("_Ok"); }
チェック、動作します!
まとめ
, , , .
Chrome ajax . .
便利なリンク:
http://jquery.com
http://habrahabr.ru/post/161895/
http://habrahabr.ru/post/154687/
http://twitter.github.com/bootstrap/
http://habrahabr.ru/post/160177/
すべてのソースはhttps://bitbucket.org/chernikov/lessonsにあります