1。序文
前のトピックでは、knockoutjsに関連する知識ポイントをすぐに紹介し、いくつかの簡単な例を書きました。これらの例を通して、あなたがすぐにKnockoutjsを始めることができることを願っています。誰もが実際のプロジェクトでKnockoutjsのアプリケーションを明確に見るために、このトピックでは、WebAPI+Bootstrap+knockoutJS+ASP.NET MVCを使用して、シングルページWebプログラムを作成する方法を紹介します。このモデルは、現在のほとんどの企業の実際のプロジェクトでも使用されています。
2。SPA(シングルページ)利点
特定の実装を導入する前に、SPAを詳細に導入する必要があると感じています。シングルページWebアプリケーションの略語であるSPAは、単一のHTMLページをロードし、ユーザーがアプリケーションと対話するときにページを動的に更新するWebアプリケーションです。ブラウザは、最初に必要なHTML、CSS、JavaScriptをロードします。すべての操作はこのページで完了し、JavaScriptによって制御されます。
シングルページプログラムの利点は次のとおりです。
ユーザーエクスペリエンスを向上させることで、ユーザーはWebアプリでネイティブアプリの速度と滑らかさを体験できます。
フロントエンドとバックエンドの懸念を分離し、フロントエンドはインターフェイスディスプレイの責任を負い、バックエンドはデータストレージとコンピューティングを担当し、それぞれ独自の義務を実行し、フロントエンドとバックエンドのロジックを一緒に混合しません。
サーバーの圧力を減らすために、ディスプレイロジックとページロジックに関係なく、サーバーはデータを生成するだけで、サーバーのスループットを増やす必要があります。 MVCのRazor構文で書かれたフロントエンドでは、サーバーがページの合成を完了してから出力する必要があります。
同じ一連のバックエンドプログラムは、変更なしでWebインターフェイス、携帯電話、タブレットなどの複数のクライアントで直接使用できます。
もちろん、上記の利点に加えて、単一ページのプログラムにも欠点があります。
SEOを助長しません。これが管理システムである場合、それはそれに影響しません。
初期負荷時間は比較的増加します。すべてのJSおよびCSSリソースが初めてロードされ、後続のページがスムーズになるためです。このために、ASP.NET MVCのバンドルを使用してファイルをバインドできます。バンドルの詳細な使用については、記事を参照してください:http://www.vevb.com/article/84329.htm、http://www.vevb.com/article/84329.htmおよびhttp://www.vevb.com/article/82174.htm。
ナビゲーションは利用できません。ナビゲートする必要がある場合は、自分で前進して後退する必要があります。このために、自分でフォワード機能とバック機能を実現して、それを補うことができます。実際、これはモバイルWebページが現在行っていることであり、今では上記のナビゲーションが必要です。これは、一部のエンタープライズバックエンド管理システムでも実行できます。
開発者の高い開発コスト。これは問題ではありません。プログラマーは請求を学習し続ける必要があります。幸いなことに、一部のフロントエンドフレームワークは非常に使いやすいです。
3. ASP.NET MVC+WebAPI+Bootstrap+KnockoutJSを使用して、SPAを実装します
SPAの利点と短所は、以前に詳細に導入されました。次に、SPAの滑らかさを体験し、元のASP.NET MVC+Razorによって作成されたページの効果を比較するために、ASP.NET MVC+WebAPI+BS+KOを使用してシングルページプログラムを実装しましょう。
1. vs2013を使用して、ASP.NET Webアプリケーションプロジェクトを作成し、MVCおよびWebAPIライブラリを確認してください。詳細については、以下の図を参照してください。
2。対応する倉庫とモデルを作成します。これが簡単なタスク管理システムです。特定のモデルと倉庫コードは次のとおりです。
タスクエンティティクラスの実装:
public enum taskState {Active = 1、Complete = 2} /// <summary> /// task entity /// </summary> public class task {public int id {get;セット; } public string name {get;セット; } public string description {get;セット; } public DateTime CreationTime {get;セット; } public dateTime finishtime {get;セット; } public string owner {get;セット; } public taskState state {get;セット; } public task(){creationtime = datetime.parse(datetime.now.tolongdatestring()); state = taskstate.active; }}タスクウェアハウジングクラスの実装:
/// <summary> ///ここで、ウェアハウスはサンプルデータをデモとして使用します。実際のプロジェクトは、データベース/// </summary> public class taskRepositoryから動的にロードする必要があります{#region static filed private static lazy <taskRepository> _taskRepository = new lazy <taskRepository>(()=> new TaskRepository(); public static taskRepository current {get {return _taskRepository.value; }} #endregion #region #region fields private readonly list <task> _tasks = new list <cask>(){new Task {id = 1、name = "create a spa program"、description = "spa(シングルページWebアプリケーション)、スパの利点は少量の帯域幅とスムーズな経験です" datetime.parse(datetime.now.adddays(1).tostring(cultureinfo.invariantculture)}、new task {id = 2、name = "Learning nockoutjs"、 "nockoutjsは、2方向バインディングをサポートするMVVMクラスライブラリです。 datetime.parse(datetime.now.adddays(2).tostring(cultureinfo.invariantculture)}、new task {id = 3、name = "Learn Angularjs"、 "AngularjsはMVVMフレームワークです。 datetime.parse(datetime.now.adddays(3).tostring(cultureinfo.invariantculture)}、new task {id = 4、 "Learn asp.net MVC Webサイト"、description = "glimpseは.netの下でのパフォーマンステストツールです。元のプロジェクト、およびコード実行の各リンクの実行時間を出力することができます」、所有者= "Tonny li"、finishtime = datetime.parse(datetime.now.adddays(4).toString(cultureinfo.invariantculture))}、}; #endregion #region public method public ienumerable <task> getall(){return _tasks; } public task get(int id){return _tasks.find(p => p.id == id); } public task add(task item){if(item == null){new argumentnullexception( "item"); } item.id = _tasks.count + 1; _tasks.add(item);返品アイテム。 } public void remove(int id){_tasks.removeall(p => p.id == id); } public bool update(task item){if(item == null){throw new argumentnullexception( "item"); } var taskitem = get(item.id); if(taskItem == null){return false; } _tasks.remove(taskItem); _tasks.add(item); trueを返します。 } #endregion}3. nugetを介してブートストラップとknockoutjsライブラリを追加します。
4.バックエンドデータサービスを実装します。ここでは、ASP.NET WebAPIを使用してバックエンドサービスが実装されます。特定の実装コードは次のとおりです。
/// <summary> ///タスクWebapi、データサービスを提供する/// </summary> public class taskscontroller:apicontroller {private readonly taskRepository _taskRepository = taskRepository.current; public iEnumerable <cask> getall(){return _taskRepository.getAll()。orderby(a => a.id); } public task get(int id){var item = _taskRepository.get(id); if(item == null){new httpresponseException(httpstatuscode.notfound); } return item; } [route( "api/tasks/getbystate")] public iEnumerable <task> getByState(string state){iEnumerable <cask> results = new list <task>(); switch(state.tolower()){case "":case "all":results = _taskRepository.getAll();壊す;ケース "Active":results = _taskRepository.getAll()。ここで(t => t.State == taskState.active);壊す; case "完了":results = _taskRepository.getAll()。壊す; } results = results.orderby(t => t.id);結果を返します。 } [httppost] public task create(task item){return _taskrepository.add(item); } [httpput] public void put(task item){if(!_taskrepository.update(item)){throw httpresponsexception(httpstatuscode.notfound); }} public void delete(int id){_taskRepository.remove(id); }}5. ASP.NET MVCバンドルを使用して、リソースをパッケージ化します。対応するBundleconfig実装コードは次のとおりです。
/// <summary> ///欠落しているCSSおよびJSファイルを追加するだけです。テンプレートの作成時に一部のCSSおよびJSファイルが追加されているため/// scriptbundle( "〜/bundles/jquery")。 bundles.add(new ScriptBundle( "〜/bundles/jqueryval")。 // Modernizrの開発バージョンを使用して、開発して学習します。次に、//生産の準備ができたら、http://modernizr.comのビルドツールを使用して、必要なテストのみを選択します。 bundles.add(new ScriptBundle( "〜/Bundles/Modernizr")。 bundles.add(new ScriptBundle( "〜/bundles/bootstrap"))。 bundles.add(new StyleBundle( "〜/content/css")。 bundles.add(new ScriptBundle( "〜/bundles/knockout")。 bundles.add(new ScriptBundle( "〜/bundles/app")。 }}
6.ページ上の文字列としてenumタイプを表示する必要があるためです。列挙は、デフォルトでシリアル化すると数値タイプに変換されます。したがって、WebApiconFigクラスに次の変更を行う必要があります。
public static class webapiconfig {public static voidレジスタ(httpconfiguration config){// web api configuration and services // web apiルーティングconfig.maphttpattributeroutes(); config.routes.maphttproute(name: "defaultapi"、routeTemplate: "api/{controller}/{id}"、defaults:new {id = routeparameter.optional}); //シリアル化を使用してキャメルケーススタイルシリアル化プロパティConfig.formatter.jsonformatter.serializersettings.contractresolver = new camelcasepropertynamescontractresolver(); //文字列config.formatters.jsonformatter.serializersettings.converters.add(new StringenumConverter())をシリアル化する; }}注:キャメル小文字のシリアル化が上で使用されていない場合は、ページ上のデータをバインドするときに調整する必要があります。たとえば、名前の属性をバインディングする場合、名前の大文字化を直接使用します。名前メソッドを使用すると、この属性に定義エラーがないことが促されます。 JSはキャメル小文字スタイルを使用して変数に名前を付けているためです。したがって、シリアル化にはキャメル小文字スタイルを使用することをお勧めします。この時点で、「名前」の形式を使用してバインドできます。これは、JSコードの仕様に沿ったものです。
7.対応するレイアウトファイルとインデックスファイルコンテンツを変更します。
レイアウトファイルの特定のコードは次のとおりです。
<!Doctype html> <html> <head> <meta charset = "utf-8"/> <meta name = "viewport" content = "width =" width = "width = 1.0"> <title> learninghard application </title> @styles.render( "〜/content/css") <div> <div> <div> <p>シンプルなタスク管理システム</p> </div> <div> <ul> <li> <a href = "/"> home </a> </li> </ul> </div> </div> </div> <div div = "main"> @renderbody()<hr/> <footer> <p>© @datetime.now.non </footer> </div> @scripts.render( "〜/bundles/jquery") @scripts.render( "〜/bundles/bootstrap") @scripts.render( "〜/bundles/knockout") @scripts.render( "〜/bundles/nockout") @scripts.render( " @{viewbag.title = "index"; layout = "〜/views/shared/_layout.cshtml";} <div id = "list" data-bind = "if:cancreate"> <h2> tasks </h2> <div> <thead> <tr> <th thth <thth </th> <th> </th> </th> </th> <th>完了時間</th> <th> statu </th> <th> </th> </tr> </t> <tbody data-bind = "foreach:tasks"> <tr> <td data-bind = "text:id"> </td> <td> <td> <td> <td> <td> <td> <td> <td> <td> <td> <td> <td> <td>説明 "> </td> <td data-bind =" text:owner "> </td> <td data-bind =" text:creationtime "> </td> <td data-bind =" text:finishtime "> </td> <td data-bind =" text:state "> </td> <td> <a bind =" clik " href = "javascript:void(0)"> remove </a> </td> </tbody> </table> </table> </div> <div> <a href = "javascript:void(0)" data-bind = "click:function(data、event){setasklist( 'all')}" <a href = "javascript:void(0)" data-bind = "click:function(data、event){setasklist( 'active')}"> active </a> | <a href = "javascript:void(0)" data-bind = "click:function(data、event){setasklist( 'complete')}">完了</a> </div> <div> <a href = "javascript:void(0)" data-bind = "" createdate ">"> ">">非表示 "> <h2>タスクの追加</h2> <br/> <div> <div> <div> <label for =" taskname "> name*</label> <div> <入力タイプ=" Text "data-bind =" value:name "id =" taskname "name =" taskname "placeholder =" name "> </div div div </</</</</</</</< data-bind = "value:" rows = "3" id = "taskdesc" name = "taskdesc" placeholder = "descripter"> </textarea> </div> </div> <div> <label for = "taskowner">担当者*</label> <div> <input id = "taskowner" name = "balle </div> <div> <label for = "taskfinish">推定完了時間*</label> <div> <入力id = "taskfinish" data-bind = "value:" finishtime "name"> "taskfinish"> </div> </div> <div> <label for = "taskowner"> status*</labe> <opts "> <</sictate" opts "> < <オプション>完了</option> </select> </div> </div> <div> <div> <ボタンdata-bind = "click:handlesaveclick"> save </button> <button data-bind = "click:click:handlebackclick"> </div> </div> </div> </div>8。対応するフロントエンドスクリプトロジックを作成します。 JSコードを使用してデータをリクエストし、対応するViewModelオブジェクトを作成してフロントエンドバインディングを作成します。特定のJS実装コードは次のとおりです。
var tasklistviewmodel = {tasks:ko.observablearray()、cancreate:ko.observable(true)}; var taskmodel = function(){this.id = 0; this.name = ko.observable(); this.description = ko.observable(); this.finishtime = ko.observable(); this.owner = ko.observable(); this.state = ko.observable(); this.fromjs = function(data){this.id = data.id; this.name(data.name); this.description(data.description); this.finishtime(data.finishtime); this.owner(data.Owner); this.state(data.state); };}; function getalltasks(){sendajaxrequest( "get"、function(data){tasklistviewmodel.tasks.removeall(); });} function setaskList(state){sendajaxrequest( "get"、function(data){tasklistviewmodel.tasks.removeall(); });} function remove(item){sendajaxrequest( "delete"、function(){getalltasks();}、item.id);} var task = new taskmodel(); function handlecreateorupdate(item){task.fromjs(item); initdatePicker(); TaskListViewModel.Cancreate(false); $( '#create')。css( 'visibility'、 'visible');} function handlebackclick(){tasklistviewmodel.cancreate(true); $( '#create')。css( 'visibility'、 'hidden');} function handlesaveclick(item){if(item.id == undefined){sendajaxrequest( "post"、function(newitem){// newItemは返されたオブジェクトです。 item.description、finishtime:item.finishtime、所有者:item.owner、state:item.state}); } else {sendajaxRequest( "put"、function(){getAlltasks();}、null、{id:item.id、name:item.name、description:item.description、finishtime:item.finishtime、所有者:item.owner、state.state}); } tasklistviewmodel.cancreate(true); $( '#create')。css( 'visibility'、 'hidden');} function sendajaxrequest(httpmethod、callback、url、reqdata){$ .ajax( "/api/tasks" +(url? "/" + url: "")、{type:httpmethod、callbback: initdatePicker = function(){$( '#create .datepicker')。datePicker({autoclose:true});}; $( '。nav')。 $(this).addclass( 'Active');}); $(document).ready(function(); // knokaltjsを使用してko.applybindings(tasklistviewmodel、$( '#list')。この時点で、当社の単一ページプログラムが開発されました。次に、その効果を確認するために実行しましょう。
上記の実行結果デモンストレーション図から、ページが読み込まれると、すべての操作が1つのページで動作しているように見えることがわかり、ブラウザページが循環しているように感じます。以前にASP.NET MVC + Razorを使用して開発されたページと比較して、スパの滑らかさを感じますか?以前は、ASP.NET MVC + Razorを使用して開発されたページは、1つのページをリクエストするだけで、ページ全体の更新を感じることができます。これにより、ユーザーエクスペリエンスが非常に悪くなります。
4。レーザー開発モデルとの比較
誰もが結果からスパの利点を見たと思います。次に、Webページを実装する従来の方法と比較する必要があると思います。かみそりの開発方法から2つの主な違いがあります。
1.ページがレンダリングされると、データはブラウザ側で処理されます。サーバー上ではありません。各ユーザーのブラウザ側にレンダリング圧力を割り当てて、ウェブサイトサーバーの圧力を削減します。かみそりの構文の場合、フロントエンドページのバインディングステートメントは次のとおりです。
@model ienumerable <knockoutjsspa.models.task> @foreach(var item in model){<tr> <td>@item.name </td> <td>@item.description </td> </tr>}これらは、サーバー側のRazorエンジンによってレンダリングされます。これが、Razorを使用して開発されたページがページが旋回する理由でもあります。ページを切り替えるたびに、サーバーにレンダリングを要求する必要があり、サーバーがレンダリングした後、HTMLをクライアントに返して表示します。
2。バインドされたデータは動的です。これは、データモデルの変更がすぐにページに反映されることを意味します。この効果は、KnockoutJSによって実装された双方向結合メカニズムに起因します。
この方法を使用することは、プログラム開発にも簡単です。 Web APIはデータの提供のみを担当し、フロントエンドページは多くのDOM操作も削減します。 DOM操作は複雑でエラーが発生しやすいためです。これは、プログラムの暗黙のバグを減らすことも意味します。さらに、バックエンドサービスを携帯電話、Webブラウザー、複数のプラットフォームで使用して、繰り返し開発を避けることができます。
5。概要
この時点で、この記事の紹介が紹介されます。この記事では、主にSPAプログラムを完了するためにKnockoutjsの使用を紹介します。実際、実際の作業では、シングルページプログラムを作成するモデルは、AngularJSにより基づいています。その後、多くのknockoutjsがありますが、knockoutjsは単なるMVVMフレームワークであり、そのルーティングメカニズムは、ASP.NET MVCのルーティングメカニズムなど、他のクラスライブラリで使用する必要があります。 KnockoutJSと比較して、AngularJSはMVVM+MVCフレームワークです。そのため、次のトピックでは、AngularJSを使用して単一ページプログラム(SPA)を作成する方法を紹介します。
この記事ですべてのソースコードをダウンロードしてください:SpawithKnockoutjs
それでも詳細に勉強したい場合は、ここをクリックして3つのエキサイティングなトピックを勉強して添付できます。
ブートストラップ学習チュートリアル
ブートストラップ実用的なチュートリアル
ブートストラッププラグインの使用チュートリアル
上記はこの記事に関するものです。すべての人の学習に役立つことを願っています。