65.9K
CodeProject 正在变化。 阅读更多。
Home

配置 Angular Material 与 Require JS

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2016 年 10 月 1 日

CPOL

6分钟阅读

viewsIcon

21992

downloadIcon

263

如何配置 Angular Material 与 Requires JS (AMD)

引言

在这篇文章中,我将分享我在 Require.js (AMD) 中配置 Angular-Material 的经验。本文将涵盖以下几点:

  • Require.Js Angular Material 配置
  • 在 html 页面中调用 angular material 日历控件
  • 提供源代码

背景

查看者应具备 Angular JS、Require JS、HTML 5、CSS 3 的中级知识。Require.js 是一个 JavaScript 类,用作模块化脚本加载器。模块化脚本加载器将提高代码的速度和质量。

要了解更多关于 require js 的信息,请单击此处

要了解更多关于 Angular Material Design 的信息,请单击此处

Using the Code

我将使用 Visual Studio 2013 IDE 来创建一个新的 angular-material 应用程序。您可以使用任何 IDE 并使用 node 包管理器 (npm) 来下载这些包。我想开始创建一个新的应用程序,使用 angular.jsangular-material.jsrequire.js。那么,让我们开始吧。打开您的 VS 2013 并创建一个新的空 Web 应用程序,命名为 DemoApp

现在,从 nuget 包中添加一些 js 框架。让我分享一下包的列表。

<packages>
  <package id="Angular.Material" version="1.1.1" targetFramework="net451" />
  <package id="angular-moment" version="0.10.3" targetFramework="net451" />
  <package id="jQuery" version="3.1.1" targetFramework="net451" />
  <package id="Moment.js" version="2.15.1" targetFramework="net451" />
  <package id="RequireJS" version="2.3.2" targetFramework="net451" />
</packages>

我添加了一个名为 ui-router 的库,用于在 angular.js 中进行路由。我从 node 控制台下载了这个包。您也可以直接从此处下载。

现在,我将分享我的文件夹结构,如下所示:

好的,让我逐行解释文件夹结构。第一个是 content 文件夹,其中包含 angular-material.css 的 CSS 文件;下一个是 CSS 文件夹,用于自定义 CSS;然后是 font 文件夹;接着是 libs 文件夹,libs 用于 angular、angular-material、Jquery 等所有 js 框架...

下一个是 main 文件夹,其中包含所有自定义 js 文件,如 controllerdirectivefilters 等。

现在,我将在 main 文件夹中添加另外两个 js 文件,分别命名为 main.jsapp.js

让我们从 main.js 文件开始,它将用于配置所有 js 库。代码如下:

require.config({
    urlArgs: "v=" + new Date().getTime(),
    waitSeconds: 300,
    baseUrl: "/",
    paths: {
        app: "main/app",
        angular: "libs/angular/angular.min",
        uirouter: "libs/ui-router/angular-ui-router.min",
        jquery: "libs/jquery/jquery-3.1.1.min",
        ngMaterial: 'libs/angular-material/angular-material.min',
        'ng-animate': 'libs/angular-animate/angular-animate.min',
        ngAria: 'libs/angular-aria/angular-aria.min',
        ngMessages: 'libs/angular-messages/angular-messages.min',
        'hammer': 'libs/hammer/hammer.min',
        'hammerProxy': 'main/hammer-proxy'
    }

创建 require 对象并调用 config 方法。在 config 方法中,我们的第一个参数是 urlArgs -> "v=" + new Date().getTime()。此参数用于在加载时对 js 文件进行版本控制,它将解决缓存问题。

接下来是 waitSeconds : n 毫秒它用于告诉 require js 在放弃加载脚本之前等待 n 秒。默认情况下,它是 7 毫秒。

下一个是 baseUrlbaseUrl 通常设置为与页面顶层脚本使用的 data-main 属性相同的目录。data-main 属性定义在 index.html 页面或 default.html 页面中。

<!--This sets the baseUrl to the "scripts" directory, 
and loads a script that will have a module ID of 'main'-->
 <script data-main="scripts/main.js" src="scripts/require.js"></script> 

下一节是 pathsPath 对象包含库 namepath 的键值对,您可以自己定义 name,而 paths 是库的路径。

shim: {
        app: {
            exports: "app",
            deps: [
                "angular", "ngMessages", "ngMaterial",  
                "uirouter",  "hammer", "hammerProxy"
            ]
        }

下一节是 Shim:shim 配置依赖项、导出和自定义初始化。Shim 配置仅用于非 AMD 脚本。在 shim 配置中,app 对象用于在 index 或 default 页面的初始化时加载重要的依赖项。一旦依赖项加载完成,它将导出全局变量 app 作为模块级。Exports 用于为模块创建一个空对象,该对象可立即供其他模块引用。

现在,让我们分享 main.js 文件的代码。

require.config({
    urlArgs: "v=" + new Date().getTime(),
    waitSeconds: 300,
    baseUrl: "/",
    paths: {
        app: "main/app",
        angular: "lib/angular/angular.min",
        uirouter: "lib/ui-router/angular-ui-router.min",
        jquery: "lib/jquery/jquery-3.1.1.min",
        ngMaterial: 'lib/angular-material/angular-material.min',
        'ng-animate': 'lib/angular-animate/angular-animate.min',
        ngAria: 'lib/angular-aria/angular-aria.min',
        ngMessages: 'lib/angular-messages/angular-messages.min',
        'hammer': 'lib/hammer/hammer.min',
        'hammerProxy': 'main/hammer-proxy'
    },
    shim: {
        app: {
            exports: "app",
            deps: [
                "angular", "ngMessages", "ngMaterial",  "uirouter",  "hammer", "hammerProxy"
            ]
        },
        angular: {
            exports: "angular"
        },
        jquery: {
            exports: "$"
        },
        uirouter: {
            deps: [
                "angular"
            ]
        },
       'ng-animate': {
            deps: ['angular']
        },

        ngAria: {
            deps:[ 'angular']
        },
        ngMessages : {
                deps: ['angular']
        },
        
        hammerProxy:
        {
            deps: ['hammer']
        },
        hammer:{
            exports: "Hammer"
        },
        ngMaterial: {
            deps: ['angular', 'ng-animate', 'ngAria']
        }
    }
});

depsdeps 首先解析依赖模块的依赖关系,然后加载实际模块。例如,ngMessages 需要先加载 angular.js

现在,还有几行代码

require(["app", "jquery", 
"main/routes/route", "main/utility/menuUtility"], function () {
    angular.element(document).ready(function () {
        angular.bootstrap(document, ["angbaseApp"]); // this line is used to bootstrap the angular 
              //and add the 'angbaseApp' as module, it means no need to add the ng-module explicitly.
    });
});

在上面的代码行中,我正在注入全局模块 app、jquery 和更多文件。所有这些脚本都需要在 dom 就绪之前加载。现在我们的 main.js 准备好了。

现在,我将创建一个 app.js 文件。

define(["app"], function () {

    var app = angular.module("angbaseApp", [ "ui.router", 
    "ngAnimate", "ngAria", "ngMessages", "ngMaterial"]);

    // Here "app" global module register all the providers 
    // To know more about providers follow the angular online documentation.
    app.config(function ($routeProvider, $controllerProvider, $provide, $compileProvider, $filterProvider, $httpProvider) {
        app.register = {
            controller: $controllerProvider.register,
            directive: $compileProvider.directive,
            filter: $filterProvider.register,
            factory: $provide.factory,
            service: $provide.service
        };               
    });    

    //Configure the angular-material theme.
    app.config(function($mdThemingProvider) {
        $mdThemingProvider.theme('dark-blue').backgroundPalette('blue').dark();
    });

    return app;
});

在上面的代码行中,我使用了 define 来定义模块,在 requirejs 中,模块是模块模式 (JavaScript) 的扩展。

在第一行,我定义了全局 app 模块。如果还有其他模块依赖于此模块,那么我们也需要定义它们,例如。

define(["app", "main/services/accountService", "main/utility/requestHeader"],例如,我定义了一个 accountServicerequestHeader 模块。

app.js 文件中,我们将注入所有 angular 模块,并进行所有必需的 angular 配置。

现在,我将添加一个 route.js 文件来为我们的 angular 应用程序进行路由。代码如下:

define(['app'], function (app) {
    'use strict';

    return app.config(['$stateProvider', '$urlRouterProvider', 
              function ($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/')

        $stateProvider            
           .state('RequireLand', {
               url: '/RequireLand',
               templateUrl: 'view/partial/view_demo.html',              
               resolve: {
                   load: function ($q, $rootScope) {
                       var defer = $q.defer();
                       require(["main/controllers/requireEnableCtrl"], function () {
                           defer.resolve();
                           $rootScope.$apply();
                       });

                       return defer.promise;
                   }
               },
               controller: "MainCtrl"
           })          
    }]);
}); 

Define 已经讨论过。在这里,我为路由进行了单独的配置,因为我使用了 ui.route 并注入了 '$stateProvider' 和 '$urlRouterProvider',我将不在此讨论 ui.route 库。请阅读 ui-route 的在线文档。

在上面的代码行中,我定义了一个名为 'RequireLand' 的状态,定义了路由的 url、模板 url,并将控制器解析到此状态。它将解析控制器文件及其依赖项。

现在,我将添加另一个名为 'requireEnableCtrl' 的 angular 控制器 js 文件,模块名为 MainCtrl。我将分享下面的代码。

define(["app"], function (app) {
    // We register a controller here
    app.register.controller("MainCtrl", function ($scope, $rootScope, $state) {
        
        // Few lines of code for my angular-material calender control.
        $scope.myDate = new Date();
        $scope.minDate = new Date(
            $scope.myDate.getFullYear(),
            $scope.myDate.getMonth() - 2,
            $scope.myDate.getDate());
        $scope.maxDate = new Date(
            $scope.myDate.getFullYear(),
            $scope.myDate.getMonth() + 2,
            $scope.myDate.getDate());
        $scope.onlyWeekendsPredicate = function (date) {
            var day = date.getDay();
            return day === 0 || day === 6;
        };       
    });
});

现在,我将添加 menuUtility.js 文件,用于定义默认路由,或者您可以使用它进行基本初始化,例如动态菜单等。此文件的代码如下:

我用它来重定向路由。

define(["app"], function (app) {
    app.controller("MenuCtrl", function ($scope, $rootScope, $state) {
        //this will tell default page to load state RequiredLand
        // And it will load the partial page i.e, already configured in routejs file
        $state.go('RequireLand'); 
    });
});

现在,我将为 View 添加一个文件夹结构。它应该是 view -> partial 用于部分视图,view -> shared 用于菜单、页眉、页脚等的共享视图。

让我在此分享我的 html 代码。首先,我想添加一个 default.html 文件作为我的登录页面,然后我将添加一个部分视图文件。两个文件的代码都如下:

//code for default.html file<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Report System</title>

    <link href="content/angular-material.min.css" rel="stylesheet" />

</head>
<body ng-controller="MenuCtrl">

    <script data-main="main/main.js" src="libs/require/require.js"></script>
    /* ng-clock directive and other ui-view directive 
       read the online documentation of angular and ui-router documentation */
    <div ng-cloak>        
        <ui-view></ui-view>
    </div>

</body>
</html>

现在,我将添加一个名为 view_demo.html 的 HTML 页面,它是一个部分页面。代码如下:

<div layout="column" layout-align="center center">
    <md-card  md-theme-watch>
        <md-card-title>
            <md-card-title-text>
                <span class="md-headline">Card with image</span>
                <span class="md-subhead">Extra Large</span>
                 
            </md-card-title-text>
        </md-card-title>
        <md-card-content layout="row" layout-align="space-between">
            <div class="md-media-xl card-media">
                <div flex-gt-xs>
                    <h4>Standard date-picker</h4>
                    <md-datepicker ng-model="myDate" md-placeholder="Enter date"></md-datepicker>
                </div>
            </div>

            <md-card-actions layout="column">
                <md-button class="md-icon-button" aria-label="Favorite">
                    <md-icon md-svg-icon="img/icons/favorite.svg"></md-icon>
                </md-button>
                <md-button class="md-icon-button" aria-label="Settings">
                    <md-icon md-svg-icon="img/icons/menu.svg"></md-icon>
                </md-button>
                <md-button class="md-icon-button" aria-label="Share">
                    <md-icon md-svg-icon="img/icons/share-arrow.svg"></md-icon>
                </md-button>
            </md-card-actions>
        </md-card-content>
    </md-card>
</div>

此页面定义了内置的 angular-material 指令。有关更多详细信息,您可以查阅其在线文档。我正在创建一个带有 datepicker 控件的卡片。

现在,我们将使用 data-main 属性在 script 元素中调用 main.js 文件,并使用 src 属性调用 require.js 文件。您需要在主页面上写这一行,例如在我的情况下,我已将此行写在我的 default.html 页面中。

 <script data-main="main/main.js" src="libs/require/require.js"></script>

现在,我将浏览我的 default.html

关注点

好了,希望您喜欢这篇文章。源代码已附上。我正在尝试涵盖基本的 require 配置,要了解更多关于 requirejs、angularjs、angular-materialjs 的信息,请阅读他们提供的在线文档。

Angularjs 主要提供基于模块的注入,而 Requirejs 提供基于类的注入 (js 文件)。

如果这篇文章在某些方面帮助了您,请投票支持本文。谢谢。

历史

  • 2016 年 10 月 5 日:初始版本
© . All rights reserved.