ホームページ ウェブフロントエンド jsチュートリアル JavaScript MVC スタイルの超簡単実装フレームワーク_javascript スキル

JavaScript MVC スタイルの超簡単実装フレームワーク_javascript スキル

May 16, 2016 pm 04:07 PM
javascript mvc フレーム

はじめに

JavaScript フレームワーク (AngularJS、Backbone、Ember など) を使用したことのある人は、UI (ユーザー インターフェイス、フロントエンド) での mvc の動作メカニズムに精通しています。これらのフレームワークは MVC を実装しており、単一ページ内で必要に応じてビューを簡単に変更できるようにします。Model-View-Controller (mvc) の中心的な概念は、受信リクエストを処理するコントローラー、情報を表示するビュー、およびプレゼンテーション モデルです。ビジネスルールとデータアクセス用。

したがって、単一ページ内のさまざまなコンテンツを切り替える必要があるアプリケーションを作成する必要がある場合、通常は上記のフレームワークのいずれかを使用することを選択します。ただし、追加のバンドル機能なしで URL 内でビューの切り替えを実装するフレームワークだけが必要な場合は、Angular や Ember などの複雑なフレームワークを使用する必要はありません。この記事は、同じ問題を解決するために、シンプルかつ効果的な方法を使用する試みです。

コンセプト

アプリケーションのコードは、URL に「#」を使用して MVC モードのナビゲーションを実装します。アプリケーションはデフォルトの URL で開始され、ハッシュベースのコードがアプリケーション ビューを読み込み、オブジェクト モデルをビュー テンプレートに適用します。

URL の形式は次のとおりです:

http://ドメイン名/index.html#/ルート名

ビューのコンテンツは、オブジェクト モデルの値とプロパティを {{Property-Name}} の形式でバインドする必要があります。コードは、この特殊なテンプレート形式を検索し、オブジェクト モデル内のプロパティ値を置き換えます。

ajax 経由で非同期的にロードされたビューは、ページのプレースホルダーに配置されます。ビュー プレースホルダーは任意の要素 (理想的には div) にすることができますが、特別な属性が必要です。コードはこの特別な属性に基づいてビュー プレースホルダーを配置します。これは、コードの実装にも役立ちます。 URL が変更されると、シナリオが繰り返され、別のビューがロードされます。簡単そうに思えますか?以下のフロー図は、この特定の実装におけるメッセージ ジャンプを説明しています。

コードを書く

基本的なモジュール設計パターンから始めて、最後にファサード設計パターンを使用してライブラリをグローバル スコープに公開しました。

;(function(w,d,undefined){//restofthecode})(window,document);
ログイン後にコピー

ビュー要素を複数回使用できるように変数に保存する必要があります。

var_viewElement=null;//elementthatwillbeusedtorendertheview
ログイン後にコピー

URL にルーティング情報がない状況に対処するには、空白のページを表示する代わりにデフォルト ビューをロードできるように、デフォルト ルートが必要です。

var_defaultRoute=null;
ログイン後にコピー

次に、メイン MVC オブジェクトのコンストラクターを作成しましょう。ルーティング情報を「_routeMap」に保存します

var jsMvc = function () {
  //mapping object for the routes
  this._routeMap = {};
}
ログイン後にコピー

ルーティング オブジェクトを作成します。このオブジェクトにルーティング、テンプレート、コントローラー情報を保存します。

var routeObj = function (c, r, t) {
  this.controller = c;
  this.route = r;
  this.template = t;
}
ログイン後にコピー

各 URL には専用のルーティング オブジェクト、routeObj があり、これらのオブジェクトはすべて _routeMap オブジェクトに追加されるため、後でキーと値を介して取得できます。

MVC ライブラリにルーティング情報を追加するには、ライブラリ内のメソッドを公開する必要があります。そこで、それぞれのコントローラーで新しいルートを追加するために使用できるメソッドを作成しましょう。

jsMvc.prototype.AddRoute = function (controller, route, template) {
  this._routeMap[route] = new routeObj(controller, route, template);
}
ログイン後にコピー

メソッド AddRoute は、コントローラー、ルート、テンプレートの 3 つのパラメーターを受け取ります。それらは次のとおりです:

コントローラー: コントローラーの機能は、特定のルートにアクセスすることです。

ルート: ルーティングのルート。 URLの#以降の部分です。

テンプレート: これは、このルートのビューとしてロードされる外部 HTML ファイルです。ここで、ライブラリには URL を解析し、関連する HTML テンプレート ページを提供するためのエントリ ポイントが必要です。これを達成するには、メソッドが必要です。

Initialize メソッドは次のことを行います:

1) ビュー関連要素の初期化を取得します。このコードには、HTML ページ内での検索に使用できる view 属性を持つ要素が必要です:

2) デフォルトルートを設定します

3) ビュー要素が妥当かどうかを検証します

4) ウィンドウのハッシュ変更イベントをバインドし、URL の異なるハッシュ値が変更されると、時間内にビューを更新できます

5) 最後に、mvc を開始します

//Initialize the Mvc manager object to start functioning
jsMvc.prototype.Initialize = function () {
  var startMvcDelegate = startMvc.bind(this);
 
  //get the html element that will be used to render the view 
  _viewElement = d.querySelector('[view]');    
  if (!_viewElement) return; //do nothing if view element is not found  
 
  //Set the default route
  _defaultRoute = this._routeMap[Object.getOwnPropertyNames(this._routeMap)[0]];  
 
  //start the Mvc manager
  w.onhashchange = startMvcDelegate;
  startMvcDelegate();
}
ログイン後にコピー

上記のコードでは、startMvc メソッドからプロキシ メソッド startMvcDelegate を作成しました。このエージェントは、ハッシュ値が変更されるたびに呼び出されます。以下は、ハッシュ値が変更されたときに実行する一連の操作です:

1)ハッシュ値を取得します

2) ハッシュからルーティング値を取得します

3) ルートマップオブジェクト_routeMap

からルートオブジェクトrouteObjを取得します。

4) URL にルーティング情報がない場合は、デフォルトのルーティング オブジェクトを取得する必要があります

5) 最後に、このルートに関連するコントローラーを呼び出し、このビュー要素のビューにサービスを提供します

上記のすべての手順は、以下の startMvc メソッドによって実装されます

//function to start the mvc support
function startMvc() {
  var pageHash = w.location.hash.replace('#', ''),
    routeName = null,
    routeObj = null;        
     
  routeName = pageHash.replace('/', ''); //get the name of the route from the hash    
  routeObj = this._routeMap[routeName]; //get the route object  
 
  //Set to default route object if no route found
  if (!routeObj)
    routeObj = _defaultRoute;
   
  loadTemplate(routeObj, _viewElement, pageHash); //fetch and set the view of the route
}
ログイン後にコピー

  下一步,我们需要使用XML HTTP请求异步加载合适的视图。为此,我们会传递路由对象的值和视图元素给方法loadTemplate。

//Function to load external html data
function loadTemplate(routeObject, view) {
  var xmlhttp;
  if (window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp = new XMLHttpRequest();
  }
  else {
    // code for IE6, IE5
    xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
  }
  xmlhttp.onreadystatechange = function () {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
      loadView(routeObject, view, xmlhttp.responseText);
    }
  }
  xmlhttp.open('GET', routeObject.template, true);
  xmlhttp.send();
}
ログイン後にコピー

  当前只剩加载视图和将对象模型与视图模板绑定了。我们会创建一个空的模型对象,然后传递与方法相关的模型来唤醒路由控制器。更新后的模型对象会与先前已经加载的XHR调用中的HTML模板绑定。

  loadView方法被用于调用控制器方法,以及准备模型对象。

  replaceToken方法被用于与HTML模板一起绑定模型

//Function to load the view with the template
function loadView(routeObject, viewElement, viewHtml) {
  var model = {}; 
 
  //get the resultant model from the controller of the current route 
  routeObject.controller(model); 
 
  //bind the model with the view  
  viewHtml = replaceToken(viewHtml, model); 
   
  //load the view into the view element
  viewElement.innerHTML = viewHtml; 
}
 
function replaceToken(viewHtml, model) {
  var modelProps = Object.getOwnPropertyNames(model),
     
  modelProps.forEach(function (element, index, array) {
    viewHtml = viewHtml.replace('{{' + element + '}}', model[element]);
  });
  return viewHtml;
}
ログイン後にコピー

  最后,我们将插件曝光于js全局范围外

//attach the mvc object to the window
w['jsMvc'] = new jsMvc();
ログイン後にコピー

  现在,是时候在我们单页应用中使用这个MVC插件。在下一个代码段中,下面这些会实现:

  1)在web页面中引入这个代码

  2)用控制器添加路由信息和视图模板信息

  3)创建控制器功能

  4)最后,初始化lib。

  除了上面我们需要的链接让我们导航到不同的路径外,一个容器元素的视图属性包含着视图模板html。

<!DOCTYPE html>
<html>
<head>
  <title>JavaScript Mvc</title>
  <script src="jsMvc.js"></script>
  <!--[if lt IE 9]> <script src="jsMvc-ie8.js"></script> <![endif]-->
   
  <style type="text/css">
    .NavLinkContainer {
      padding: 5px;
      background-color: lightyellow;
    }
 
    .NavLink {
      background-color:black;
      color: white;
      font-weight:800;
      text-decoration:none;
      padding:5px;
      border-radius:4px;
    }
      .NavLink:hover {
        background-color:gray;
      }
  </style>
</head>
<body>
  <h3>Navigation Links</h3>
  <div class="NavLinkContainer">
    <a class="NavLink" href="index.html#/home">Home</a> 
  
    <a class="NavLink" href="index.html#/contact">Contact</a> 
 
    <a class="NavLink" href="index.html#/admin">Admin</a> 
    
  </div>
  <br />
  <br />
  <h3>View</h3>
  <div view></div>
  <script>
    jsMvc.AddRoute(HomeController, &apos;home&apos;, &apos;Views/home.html&apos;);
    jsMvc.AddRoute(ContactController, &apos;contact&apos;, &apos;Views/contact.html&apos;);
    jsMvc.AddRoute(AdminController, &apos;admin&apos;, &apos;Views/admin.html&apos;);
    jsMvc.Initialize();
 
    function HomeController(model) {
      model.Message = &apos;Hello World&apos;;
    }
 
    function ContactController(model) {
      model.FirstName = "John";
      model.LastName = "Doe";
      model.Phone = &apos;555-123456&apos;;
    }
 
    function AdminController(model) {
      model.UserName = "John";
      model.Password = "MyPassword";
    }
  </script>
</body>
</html>
ログイン後にコピー

  上面的代码有一段包含一个为IE的条件注释。

<!--[if lt IE 9]> <script src="jsMvc-ie8.js"></script> <![endif]-->
ログイン後にコピー

  如果IE的版本低于9,那么function.bind,Object.getOwnPropertyNames和Array.forEach属性将不会被支持。因此我们要通过判断浏览器是否低于IE9来反馈代码是否支持。

  其中的内容有home.html, contact.html 和 admin.html 请看下面:

  home.html:

{{Message}}
ログイン後にコピー

  contact.html:

{{FirstName}} {{LastName}}
<br />
{{Phone}}
ログイン後にコピー

  admin.html:

<div style="padding:2px;margin:2px;text-align:left;">
  <label for="txtUserName">User Name</label>
  <input type="text" id="txtUserName" value="{{UserName}}" />
</div>
<div style="padding:2px;margin:2px;text-align:left;">
  <label for="txtPassword">Password</label>
  <input type="password" id="txtPassword" value="{{Password}}" />
</div>
ログイン後にコピー

  完整的代码可以从给定的下载链接中得到。

 如何运行代码

  运行该代码比较简单,需要在你喜欢的Web服务器上创建一个Web应用,下面以IIS为例来说明。

  首先在默认站点中新增一个Web应用.

  然后设置必填信息:别名,物理路径,应用池,用户认证信息,点击OK。

  最后定位到Web应用的内容目录,浏览你想打开的HTML页面即可。

  跑在服务器里是必要的,因为代码加载从存储于外部文件中的视图,浏览器不会允许我们的代码在非宿主服务器环境下执行。当然如果你使用Visual Studio那么直接在目标html文件上右键,选择‘View In Browser'即可。

 浏览器支持

  大部分的现代浏览器都支持本代码。针对IE8及以下的浏览器,有一份单独的代码来支持,但很不幸,这份代码远多于100行。因此这代码不是百分百跨浏览器兼容的,所以当你决定在项目中使用时需要对代码进行微调。

 兴趣点

  This example demonstrates这个示例向我们展示了对于非常明确地需求来说,真没必要全部使用js库和框架来实现。Web应用是资源密集型的,最好只使用必要的代码而丢掉其他多余部分。

  目前的代码能做的就这些了。没有诸如Web服务调用,动态事件绑定功能的。很快我会提供支持更多特性的升级版本。

以上所述就是本文的全部内容了,希望能对大家熟练掌握javascript有所帮助。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Java フレームワークの商用サポートの費用対効果を評価する方法 Java フレームワークの商用サポートの費用対効果を評価する方法 Jun 05, 2024 pm 05:25 PM

Java フレームワークの商用サポートのコスト/パフォーマンスを評価するには、次の手順が必要です。 必要な保証レベルとサービス レベル アグリーメント (SLA) 保証を決定します。研究サポートチームの経験と専門知識。アップグレード、トラブルシューティング、パフォーマンスの最適化などの追加サービスを検討してください。ビジネス サポートのコストと、リスクの軽減と効率の向上を比較検討します。

PHP フレームワークの軽量オプションはアプリケーションのパフォーマンスにどのような影響を与えますか? PHP フレームワークの軽量オプションはアプリケーションのパフォーマンスにどのような影響を与えますか? Jun 06, 2024 am 10:53 AM

軽量の PHP フレームワークは、サイズが小さくリソース消費が少ないため、アプリケーションのパフォーマンスが向上します。その特徴には、小型、高速起動、低メモリ使用量、改善された応答速度とスループット、および削減されたリソース消費が含まれます。 実際のケース: SlimFramework は、わずか 500 KB、高い応答性と高スループットの REST API を作成します。

Golang フレームワークのドキュメントのベスト プラクティス Golang フレームワークのドキュメントのベスト プラクティス Jun 04, 2024 pm 05:00 PM

明確で包括的なドキュメントを作成することは、Golang フレームワークにとって非常に重要です。ベスト プラクティスには、Google の Go コーディング スタイル ガイドなど、確立されたドキュメント スタイルに従うことが含まれます。見出し、小見出し、リストなどの明確な組織構造を使用し、ナビゲーションを提供します。スタート ガイド、API リファレンス、概念など、包括的で正確な情報を提供します。コード例を使用して、概念と使用法を説明します。ドキュメントを常に最新の状態に保ち、変更を追跡し、新機能を文書化します。 GitHub の問題やフォーラムなどのサポートとコミュニティ リソースを提供します。 API ドキュメントなどの実践的なサンプルを作成します。

PHP フレームワークの学習曲線は他の言語フレームワークと比較してどうですか? PHP フレームワークの学習曲線は他の言語フレームワークと比較してどうですか? Jun 06, 2024 pm 12:41 PM

PHP フレームワークの学習曲線は、言語熟練度、フレームワークの複雑さ、ドキュメントの品質、コミュニティのサポートによって異なります。 PHP フレームワークの学習曲線は、Python フレームワークと比較すると高く、Ruby フレームワークと比較すると低くなります。 Java フレームワークと比較すると、PHP フレームワークの学習曲線は中程度ですが、開始までの時間は短くなります。

さまざまなアプリケーションシナリオに最適な Golang フレームワークを選択する方法 さまざまなアプリケーションシナリオに最適な Golang フレームワークを選択する方法 Jun 05, 2024 pm 04:05 PM

アプリケーションのシナリオに基づいて最適な Go フレームワークを選択します。アプリケーションの種類、言語機能、パフォーマンス要件、エコシステムを考慮します。一般的な Go フレームワーク: Jin (Web アプリケーション)、Echo (Web サービス)、Fiber (高スループット)、gorm (ORM)、fasthttp (速度)。実際のケース: REST API (Fiber) の構築とデータベース (gorm) との対話。フレームワークを選択します。主要なパフォーマンスには fasthttp、柔軟な Web アプリケーションには Jin/Echo、データベース インタラクションには gorm を選択してください。

Java フレームワークのパフォーマンス比較 Java フレームワークのパフォーマンス比較 Jun 04, 2024 pm 03:56 PM

ベンチマークによると、小規模で高性能なアプリケーションの場合、Quarkus (高速起動、低メモリ) または Micronaut (TechEmpower に優れた) が理想的な選択肢です。 SpringBoot は大規模なフルスタック アプリケーションに適していますが、起動時間とメモリ使用量が若干遅くなります。

golang フレームワーク開発の実践的な詳細な説明: 質疑応答 golang フレームワーク開発の実践的な詳細な説明: 質疑応答 Jun 06, 2024 am 10:57 AM

Go フレームワーク開発における一般的な課題とその解決策は次のとおりです。 エラー処理: 管理にはエラー パッケージを使用し、エラーを一元的に処理するにはミドルウェアを使用します。認証と認可: サードパーティのライブラリを統合し、資格情報を確認するためのカスタム ミドルウェアを作成します。同時処理: ゴルーチン、ミューテックス、チャネルを使用してリソース アクセスを制御します。単体テスト: 分離のために getest パッケージ、モック、スタブを使用し、十分性を確保するためにコード カバレッジ ツールを使用します。デプロイメントとモニタリング: Docker コンテナを使用してデプロイメントをパッケージ化し、データのバックアップをセットアップし、ログ記録およびモニタリング ツールでパフォーマンスとエラーを追跡します。

Golang フレームワークのパフォーマンス比較: 賢明な選択を行うための指標 Golang フレームワークのパフォーマンス比較: 賢明な選択を行うための指標 Jun 05, 2024 pm 10:02 PM

Go フレームワークを選択する場合、主要業績評価指標 (KPI) には、応答時間、スループット、同時実行性、リソース使用量が含まれます。フレームワークの KPI をベンチマークして比較することで、開発者は、予想される負荷、パフォーマンスが重要なセクション、リソースの制約を考慮しながら、アプリケーションのニーズに基づいて情報に基づいた選択を行うことができます。

See all articles