9

私は現在、非常に大きな単一ページの Web/JavaScript アプリケーションになるものを書いています。

私が使用しているテクノロジは、ASP.NET MVC4、jquery、knockout.js、およびmplify.js です。

私が抱えている問題は、すべてではないにしてもほとんどの単一ページ アプリケーションの例は、すべてのスクリプト テンプレート (jquery、handlbars など) が残りのファイルと同じファイルにある小さなアプリケーション用であることです。 htmlコードの。これは小規模なアプリでは問題ありませんが、私が構築しているアプリケーションは、非常に多くの画面を持つ完全なメンテナンス ロジスティクス アプリケーションです。

私がこれまでに取ったアプローチは、外部シェル (メインの index.cshtml ファイル) があり、jquery の load() メソッドを使用して、ユーザーが特定の選択をしたときに必要な特定のファイルをロードまたは挿入することです。

例:

function handleLoginClick(){

    App.mainContentContainer.delegate('#btnLogin', 'click', function() {

        App.loadModule('Home/ProductionControlMenu', App.MainMenuView.render());

    });

}

App.loadModule 関数のコードは次のとおりです。

App.loadModule = function(path, callback){

    App.mainContentContainer.load(App.siteRoot + path, callback);

};

新しくロードされた画面上のさまざまなフォーム要素と実際にやり取りを開始する必要があるまで、すべてが順調に進んでいました. jquery はそれらを直接処理できないようです。.live() または .delegate() はイベントではなく、テキスト ボックスとボタンであり、場合によっては css クラスを変更する必要があるため、使用できません。

私が見つけた唯一の方法は、外側のシェル ( .load() を介してロードされなかったもの) から要素のハンドルを取得し、jquery の .find() メソッドを次のように使用することです。

  App.mainContentContainer.find('#btnLogin').addClass('disabled');

明らかに、フォーム要素とやり取りしたり、フォーム要素から値を取得したりする必要があるたびに、このようなことをする必要はありません。

単一のファイルにすべての html コードを配置することなく、潜在的に数百の .html ファイルを含む保守可能な非常に大きな単一ページアプリケーションを作成し、それでもこの .load() 問題を回避する方法について、誰かアイデアはありますか?持っていますか?

どんな考えでも大歓迎です。:-)

V/R

クリス

アップデート

私は更新を投稿し、物事がどのように進み、何が機能したかについて投稿すると思いました. 多くの調査の結果、Google の AngularJS Javascript フレームワークを使用することにしました。それは試練を指数関数的に単純化し、私は間違いなく、大規模なSPAの作成を検討しているすべての人にそれを見てもらうようにアドバイスします.

リンク:

メインサイト http://angularjs.org/

Angular の素晴らしい無料ショート ビデオ: http://www.egghead.io/

4

8 に答える 8

12

これは実際には非常に複雑な質問であり、実際にはアーキテクチャの設計にまで及びます。

大規模なシングルページ アプリケーションの場合は、backbone.jsなどのフロントエンド MV* スタイル フレームワークを使用することをお勧めします。これは、jQuery と非常に便利に連携します。また、スクリプトと依存関係を非同期で読み込むために、 require.jsなどの依存関係管理フレームワークを使用することも検討する必要があります。さらに良いのは、アプリケーション設計で AMD パターンを使用して、アーキテクチャをモジュール化し、管理しやすくすることです。

これが MVC4 プロジェクトにどのように関連するかについては、いくつかのオプションがあります。

  1. MVC をある種の「サービス レイヤー」として使用し、JSON オブジェクトを返すだけで、フロントエンドでマークアップ/テンプレートの作成を実行できるようにするか ( handlebars.jsと考えてください)、または
  2. Razor テンプレート システムを活用し、フロント エンドを使用してサーバーから返されたものを表示する場合、MVC プロジェクトが応答として部分ビュー (HTML) を返すようにしますか?

いずれにせよ、フロントエンドのイベントとナビゲーションを処理する方法を考案する必要があります (バックボーンは、jQuery と組み合わせるとこれらの両方を提供します)。さらに複雑なのは、あるビューに別のビューのアクティビティを通知するために選択するパターンです (これには多くの方法があります)。たとえば、パブリッシュ/サブスクライブ パターンです。

質問に完全に答えていないことはわかっていますが、答えが非常に長くなる可能性があります。

于 2012-12-05T18:54:27.427 に答える
7

あなたのアプローチには多くのことが間違っています。私がお勧めするのは、人々がシングル ページ アプリケーションを構築する方法と、どのツールが主に使用されるかについてのプレゼンテーションを見ることです。

これは合理的なもののように思えます: http://singlepageappbook.com/

あなたは少なくとも欲しいでしょう

  • ある種のモジュール システム (AMD をお勧めします – <a href="http://requirejs.org">http://requirejs.org)
  • MV* フレームワーク (バックボーン、Ember.js など)
  • DOM/AJAX フレームワーク (jQuery、Mootools など)。一部のフレームワークは、これと上記のすべてを提供します (Dojo、YUI、Sencha)
  • ビルド ソリューション (開発環境と本番環境で異なる環境を用意するため)

いくつかの良いリンク:

  1. http://nerds.airbnb.com/slides-and-video-from-spike-brehms-tech-talk
  2. http://video.copenhagenjs.dk/video/3413395/simon-hjberg-swipely-building
  3. http://backstage.soundcloud.com/2012/06/building-the-next-soundcloud/
  4. http://www.youtube.com/watch?v=vXjVFPosQHw
于 2012-12-05T18:50:15.713 に答える
4

複雑な真のSOFEAシングル ページ アプリが必要ない場合は、 PJAXルートを使用することをお勧めします。

次に、アプリケーションを通常の Web 1.0 アプリケーションとして記述し、1 ページの読み込みでパフォーマンスを向上させます。サーバー側でほとんどの検証作業を行うことができるため、これをオプションとして検討することを強くお勧めします。

ページ全体からヘッダーとフッター (javascript と css インクルードを含む) を差し引いたものを返信するたびに、アイデアは非常に単純です。最近の DOM レンダリング時間は信じられないほど高速です...ページ全体のリロードではありません。したがって、返される HTML のサイズについて心配する必要はありません。

また、「PJAX 方式」は、キャッシュがはるかに簡単でGoogle SEO フレンドリーであり、実際に新しい Basecamp が行っていることです。

于 2012-12-06T18:39:00.150 に答える
3

注:これを回答ではなくコメントにしたかったのですが、コメントを投稿するのに十分な経験がありません;(
[コミュニティメンバーによる修正は大歓迎です!]

シングル ページ アプリで考慮すべき重要なポイント:

  • ユーザーが最初にページをロードしたときにすぐに何百もの js ファイルをロードしたくないため (ロード時間が非常に遅い)、遅延ロードは非常に重要です。
  • 優れたファイル編成- 変更を容易にし、複雑さを少し軽減し、再利用可能なコンポーネントを促進します。コンポーネントのテストを容易にします。
  • テスト、- シングル ページ アプリの内部では多くの JavaScript が使用されているため、コンポーネントを自動的にテストするためのテスト フレームワークが必要になります。このテストは、特定のユーザー コントロールがレンダリングされているかどうかなどを確認するために使用するテストの上にあります。ビューレス コンポーネントがサーバーに対して ajax 呼び出しを行うべきではない場合などは望ましくないからです。

フレームワークの使用に関するグリズリーのポイントに+1。

Sencha には、ExtJs 製品用の素晴らしい MVC のようなフレームワークがあります。データ ストア、ajax、遅延読み込み、クラス階層など、多くの機能がパッケージにバンドルされています。オブジェクトのプロパティとメソッドを検索するための優れたAPIページもあります(javascriptのインテリセンスがないように見えるので便利です:/ )。彼らのAPIページは; 私の知る限り、シングルページアプリの例です。ExtJs が行うことの多くは、オープン ソースの代替手段を見つけることができることを知っていますが、それが 1 つのライブラリであり、さまざまな操作を行うためにいくつかの異なるフレームワークをダウンロードする必要がないことが気に入っています。[注: 私は、Sencha の顧客であり、Sencha の製品が好きであること以外は、Sencha とは何の関係もありません。]

結論:

クライアント側のフレームワークを使用せずに、大規模な単一ページのアプリを管理するのは非常に難しいと思います。オープン ソースかどうかに関係なく、クライアント側の MVC のようなアーキテクチャ パターンを使用しません。

シングル ページ アプリはより複雑だと思います。そのため、チームはシングル ページ アプリの概念とその実装方法を理解するのに非常に便利である必要があります。サイトからそれをやってのけると、ユーザーエクスペリエンスの点で驚くべきものになります.

于 2013-03-22T14:44:16.153 に答える
0

Dojo Toolkit を使用して、巨大な単一ページ・アプリケーションをいくつか作成しました。どの JavaScript フレームワークを選択しても、おそらくうまくいくと確信しています。私が Dojo を使用しているのは、巨大な単一ページのアプリケーション開発の管理を容易にする機能を提供してくれるからです。

Dojo のウィジェット システムを使用して、すべての画面とフォームをウィジェットとして定義し、必要なときにそれらをインスタンス化して、必要な場所に挿入することができます。それを取り除きたいときはいつでも、その特定のウィジェットでdestroyorを呼び出すだけで済みます。destroyRecursiveDojo のウィジェット システムは、HTML を JavaScript から分離するのにも役立ちますが、それらがあちこちに配置されないようにまとめておくことができます。

ログインフォーム用の簡単なウィジェット定義を含めました。

これは HTML テンプレートです。

/* mine/forms/Login.html */
<div>
    ${form_name}
    <label>Username</label>
    <input data-dojo-type="dijit.form.TextBox"
           data-dojo-attach-point="_usrfld" />
    <br />
    <label>Password</label>
    <input data-dojo-type="dijit.form.TextBox"
           data-dojo-props="type: 'password'"
           data-dojo-attach-point="_pwdfld" />
    <br />
    <input data-dojo-type="dijit.form.Button"
           data-dojo-props="label: 'Login'"
           data-dojo-attach-event="onClick:_handleLogin" />
</div>

これは、ウィジェットの JavaScript 部分です。

/* mine/forms/Login.js */
define([
    "dojo/_base/declare",
    "dijit/_Widget",
    "dijit/_Templated",
    "dijit/_WidgetsInTemplateMixin",
    "dijit/form/Button",
    "dijit/form/TextBox",
    "dojo/text!./Login.html"
], function(
    declare,
    _Widget,
    _Templated,
    _WidgetsInTemplateMixin,
    Button,
    TextBox,
    template
) {

return declare("mine.forms.Login", [_Widget, _Templated, _WidgetsInTemplateMixin], {
    // assign the template
    templateString: template,

    // signal that we will have widgets within our template and the parser should 
    // locate them and instantiate them
    widgetsInTemplate: true,

    form_name: "My Login Form",

    // place holders that will be referencing the corresponding widgets
    // that I have placed a data-dojo-attach-point on
    _usrfld: null,
    _pwdfld: null,
    _lgbtn: null,

    // a call back function that will be trigger when the Login button is clicked
    _handleLogin: function() {
        var usr = this._usrfld.get('value');
        var pwd = this._pwdfld.get('value');

        // now you have the username & password
        // you can use it to login
    }
});

});

ウィジェット システムが提供するいくつかの利点があります。

  1. 必要に応じて HTML テンプレートが読み込まれます
  2. ウィジェット内にウィジェットを含めることができます。Dojo は、これらのウィジェットのインスタンス化と破棄さえも処理します。
  3. Dojo の単純なテンプレート言語を使用して、ストリングを挿入することができます。上記の例では${form_name}. より洗練された機能を使用したい場合、dojo は Django と同様の構文テンプレート言語もサポートしています。これにより、for、if-then-else など、Django で利用可能なほとんどのタグを使用できるようになります。
  4. data-dojo-attach-point非常に役に立ちます。これを使用すると、ID を DOM 要素に割り当てる必要がなくなります。HTML DOM ツリーで要素を見つける必要はありません。名前を付けた変数data-dojo-attach-pointは、テンプレートで定義したウィジェットまたは DOM 要素を参照するために自動割り当てされます。上記の例では、、、および を使用して_usrfld_pwdfldます_lgbtn
  5. data-dojo-attach-eventも非常に役立ちます。これを使用すると、ボタンに手動でイベント フックを追加する必要がなくなります。Dojo のウィジェット システムがボタンをフックし、ウィジェットが破棄されたときにフックもクリアします。
  6. Dojo のビルド システム (すべての JavaScript コードを取得して圧縮するシステム) を使用する場合、Dojo はテンプレートを実際の HTML に置き換えます。そのため、ウィジェットをプロダクション モードでロードするときに、Dojo は別の AJAX を作成する必要がありません。テンプレートを取得するように要求します。

これらは、私がプロジェクトを開発するときに毎日使用する機能のほんの一部です。プロジェクトに適切な JavaScript フレームワークを選択する際の決定に使用できる洞察が得られることを願っています。余談ですが、私は Dojo などを推奨しているわけではありません。私にとって何が効果的かを共有したかっただけです。

于 2012-12-06T06:18:22.903 に答える
0

Sammy.js を使用し、ノックアウトでさまざまなビューモデルを別の URL に分割することをお勧めします。また、asp.net mvc 4 を使用している場合は、部分ビュー (ユーザー コントロール) を使用して、すべてのコードを 1 つのファイルに格納します。そして、すべてのjsコードに名前を付けて、すべてのjsコードを意味のある方法で分割します.jsのファイル名と名前空間。これは、長い目で見れば保守性とあなた自身の健全性に大いに役立ちます。そして常識を働かせてください!

于 2012-12-05T18:40:58.930 に答える
0

私が行った方法は、テンプレート自体と一緒にテンプレートに関連する JavaScript コードを含めることでした。そして、ajax を使用してテンプレートとスクリプト全体を読み込みます。<script>これを試してみたい場合は、ほとんどのブラウザーがページに挿入されたタグを実行しないことに注意してください。特にinnerHTML. そのためeval、スクリプトは自分でタグ付けする必要があります (代わりに、document.createElement を使用してスクリプトを挿入することもできますが、ブラウザはとにかくスクリプトをやみくもに実行するため、eval と比較して追加の利点はありません)。

私の場合、テンプレートの html およびスクリプト部分を簡単に取得できるようにするために、テンプレートを単純な古い HTML ではなく XML ファイルに保存します。そうすれば、単純.responseXMLに ajax リクエストを使用してテンプレートを解析できます。私のテンプレートには、次の基本構造があります。

<template options...>
    <title>Optional</title>
    <html><![CDATA[

        Template body

    ]]></html>
    <init><![CDATA[

        // code that only needs to execute once

    ]]></init>
    <script><![CDATA[

        // code that needs to run every time
        // the template loads

    ]]></script>
</template>

また、テンプレートに適したコンテンツ タイプで応答するようにサーバーを構成することも忘れないでください。それ以外の場合resultXMLは機能しません。もちろん、これがこのシステムを実装する唯一の方法ではありません。テンプレートを HTML として保存し、その HTML を解析して実行するスクリプトを抽出するだけです。

コードの大部分、関数、コンストラクター、オブジェクトなどを js ファイルに含めることができます。テンプレート スクリプトは、これらの関数を呼び出して、ページの残りの部分にテンプレートの操作方法を伝えるだけで済みます。

テンプレートからデータをさらに分離し、テンプレートにページ上のデータのみを入力するか、JSON データに対して別の ajax 要求を行う場合は、ブラウザーがテンプレートをキャッシュするようにサーバーを構成できます。これは、頻繁に使用されるテンプレート (ダイアログ ボックスのテンプレートなど) に特に役立ちます。これにより、ブラウザーはテンプレートを 1 回だけダウンロードし、次にテンプレートを呼び出したときにキャッシュされたバージョンを使用できます。

とにかく、それは私が前回やった方法です。これは、Facebook ユーザーにサービスを提供するのに十分な拡張性を備えていました (Web アプリは Facebook アプリでした)。私の経験を共有するだけです。それが役に立てば幸い。

于 2012-12-05T18:47:30.253 に答える