web-dev-qa-db-ja.com

AngularJS-ルートに基づく外部JSの動的ロード

複数のビューと各ビューを制御するための次へ/戻るボタンを備えたシンプルな単一ページのモバイルアプリを作成しようとしています。 AngularモバイルUIライブラリを使用しています。

基本的なモックアップは次のとおりです。

<html>
    <head>
        <link rel="stylesheet" href="mobile-angular-ui/dist/css/mobile-angular-ui-base.min.css">
        <link rel="stylesheet" href="mobile-angular-ui/dist/css/mobile-angular-ui-desktop.min.css">

        <script src="js/angular/angular.min.js"></script>
        <script src="js/angular/angular-route.min.js"></script>
        <script src="mobile-angular-ui/dist/js/mobile-angular-ui.min.js"></script>

        <script src="app/app.js"></script>
        <script src="app/firstController.js"></script>
        <script src="app/secondController.js"></script>
        <script src="app/thirdController.js"></script>

    </head>

    <body ng-app="demo-app">
        <div ng-view></div>

        <div ng-controller="nextBackController" class="navbar navbar-app navbar-absolute-bottom">
            <div class="btn-group justified">
              <a href="#/" class="btn btn-navbar btn-icon-only"><i class="fa fa-home fa-navbar"></i></a>
              <a href="#/second" class="btn btn-navbar btn-icon-only"><i class="fa fa-list fa-navbar"></i></a>
            </div>
        </div>

    </body>


</html>

App.jsは次のとおりです。

var app = angular.module('demo-app', [
  "ngRoute",
  "mobile-angular-ui"
]);

app.config(function($routeProvider) {
  $routeProvider.when('/', { controller: "firstController",
                             templateUrl: "views/first.html"});
  $routeProvider.when('/', { controller: "secondController",
                             templateUrl: "views/first.html"});
  $routeProvider.when('/', { controller: "thirdController",
                             templateUrl: "views/first.html"});
});

controllers = {};

controllers.nextBackController = function($scope, $rootScope) {
    //Simple controller for the next, back buttons so we just put it in app.js
};

app.controller(controllers);

firstController.jsには次のようなものが含まれます。

controllers.firstController = function($scope) {
    //Do our logic here!!!
};

問題は、HTMLページの上部ですべてのコントローラーをロードする必要があることに気づいた場合です。これはスケーラブルではありません。ユーザーがコントローラーを必要としないこともあるため、各コントローラーを独自のJSファイルに入れ、静的にロードする必要はありません。ルートを切り替えるときに実際のJSファイルを動的にロードする方法はありますか?または、「first.html」、「second.html」などの上部にスクリプトタグを貼り付けることができます。

22
user3621014

私が正しく理解している場合、各ビューに特定のスクリプトをロードする必要がありますか? ocLazyLoader オンデマンドでモジュールをロードするプラグインを使用する個人プロジェクトからこのスニペットを共有しています。

var myApp = angular.module("myApp", [
"ui.router", 
"oc.lazyLoad",  
]); 

次に、ルーティングで動的JS/CSSファイルを適宜ロードできます。この例では、UI Selectプラグインの依存関係をロードしています

myApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {

$stateProvider

  // State
    .state('demo', {
        url: "/demo.html",
        templateUrl: "views/demo.html",
        data: {pageTitle: 'demo page title'},
        controller: "GeneralController",
        resolve: {
            deps: ['$ocLazyLoad', function($ocLazyLoad) {
                return $ocLazyLoad.load([{
                    name: 'ui.select',
 // add UI select css / js for this state
                    files: [
                        'css/ui-select/select.min.css', 
                        'js/ui-select/select.min.js'
                    ] 
                }, {
                    name: 'myApp',
                    files: [
                        'js/controllers/GeneralController.js'
                    ] 
                }]);
            }]
        }
    })
22
Raja Khoury

Gruntに慣れている場合:

https://github.com/ericclemmons/grunt-angular-templates

Gruntと上記のビルドタスクを使用して、すべてのビューから1つの.jsを作成します。ビューディレクトリ内のすべてのhtmlファイルに監視タスクリスナーを含めます。部分ビューに変更が加えられるたびに、ファイル内のすべてのhtmlとキャッシュのエイリアスを作成するURLを含む「$ templateCache」エントリが作成されます。ルートは同じ方法で部分ビューをポイントしますが、htmlファイルは存在する必要はありません。テンプレートを含む.jsファイルのみ。この利点は、一度ロードすると、セッション全体でクライアント側で使用できることです。これにより、HTTP呼び出しが削減され、トラフィックをWebサービス呼び出しのみに減らすことができます。

これは、上記のgithubリンクからのテンプレートの例です。

angular.module('app').run(["$templateCache", function($templateCache) {
$templateCache.put("home.html",
// contents for home.html ...
);
...
$templateCache.put("src/app/templates/button.html",
// contents for button.html
);
}]);

Gruntに慣れていない場合

見てみな。ビルド、ミニファイ、連結、トランスパイリングなどの自動化には非常に貴重です。

http://gruntjs.com/

7
Lee Duckworth

アプリが[〜#〜] massive [〜#〜]でない限り、小さなjsファイルを個別に提供しないでください。 。これは、質問で提案したように、必要に応じてファイルを遅延的にフェッチする方法を見つけたとしても、アプリの速度を著しく低下させます。

これを行うより良い方法(およびAngularJSチームが使用および提案する方法)は、ビルドプロセス(これにはgruntを使用する必要があります)を使用してすべてのjavascriptファイルを連結し、単一のapp.jsファイル。この方法で、必要なだけ多くの小さなjsファイルで組織化されたコードベースを維持できますが、スクリプトフェッチを1つの要求に減らすことができます。

5
Evan Drewry

OCLazyLoadのインストール方法

1。ダウンロードocLazyLoad.jshere

Gitリポジトリの「dist」フォルダーにあります。 _bower install oclazyload_または_npm install oclazyload_を使用してインストールすることもできます。

2。モジュールoc.lazyLoadをアプリケーションに追加します:

var myApp = angular.module("MyApp", ["oc.lazyLoad"]);

3。ルートに基づいて、オンデマンドでJSファイルを読み込みます:

_    myApp.controller("MyCtrl", function($ocLazyLoad){
       $ocLazyLoad.load('testModule.js');
    }});`
_

_$ocLazyLoad_を使用するとangularモジュールをロードできますが、新しいモジュールを定義せずにコンポーネント(コントローラー/サービス/フィルター/ ...)をロードする場合は完全に可能です(ちょうど既存のモジュール内でこのコンポーネントを必ず定義してください)。

_$ocLazyLoad_を使用してファイルをロードする方法は複数ありますが、好みの方法を選択してください。

また、開始したいがドキュメントだけでは不十分な場合は、「examples」フォルダーの例を参照してください。

クイックスタート

4
AllJs

標準の角度でどのように機能するのかわかりませんが、angular-ui-routerを使用できます:

コントローラーは、対応するスコープが作成されたとき、つまり、ユーザーがURLを介して手動で状態にナビゲートしたときに、必要に応じてインスタンス化されます。$ stateProviderは正しいテンプレートをビューにロードし、コントローラーをテンプレートのスコープにバインドします。

https://github.com/angular-ui/ui-router/wiki

1
BAYELK

ここで述べたように、最良の方法は RequireJS であると思います .js? それは完全に許可されており、あなたがしようとしているものに到達することができます。

ここにサンプルコードがあります

https://github.com/tnajdek/angular-requirejs-seed

1
bto.rdz

RequireJS は、この場合に非常に便利です。 RequireJSを使用して、JSファイルの依存関係を宣言できます。

this simple tutorialを参照できます。

1
Gurjaspal