zoukankan      html  css  js  c++  java
  • 基于requirejs和angular搭建spa应用

      接上篇,angular 实战部分,angular比较适合spa项目,这里不借助任何seed和构建工具,直接从零搭建,基本的angular项目结构大致包含如下几个部分:
      1)app.js 入口

      2)index.html html框架页

      3)lib(vendor)第三方类库

      4)components 业务组件

      5)styles/images 静态资源部分

    1、常规实现

      创建文件夹demo1,按照上述结构分别创建app.js ,index.html文件,创建lib、components、styles和images文件夹,最终如下图所示:

    在此基础上,我们增加三个业务组件home,about,contact,并初始化基本代码如下:

    核心代码文件

    index.html

     1 <!DOCTYPE html>
     2 <html lang="en" ng-app="app">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
     7     <title>demo1</title>
     8     <script src="https://cdn.bootcss.com/angular.js/1.6.0/angular.js"></script>
     9     <script src="https://cdn.bootcss.com/angular-ui-router/1.0.3/angular-ui-router.js"></script>
    10 
    11     <script src='./app.js'></script>
    12     <script src='./components/home/home.controller.js'></script>
    13     <script src='./components/about/about.controller.js'></script>
    14     <script src='./components/contact/contact.controller.js'></script>
    15 
    16 </head>
    17 <body>
    18     <div class="nav">
    19         <ul>
    20             <li><a ui-sref="home">Home</a></li>
    21             <li><a ui-sref="about">About</a></li>
    22             <li><a ui-sref="contact">Contact</a></li>
    23         </ul>
    24     </div>
    25     <div class="container">
    26         <div ui-view></div>
    27     </div>
    28 </body>
    29 </html>

    app.js

     1 angular.module('app', ['ui.router'])
     2     .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
     3         //默认指向
     4         $urlRouterProvider.otherwise('/home');
     5 
     6         $stateProvider.state('home', {
     7             url: '/home',
     8             templateUrl: './components/home/home.tpl.html',
     9             controller: 'HomeController',
    10             controllerAs: 'vm'
    11 
    12         }).state('about', {
    13             url: '/about',
    14             templateUrl: './components/about/about.tpl.html',
    15             controller: 'AboutController',
    16             controllerAs: 'vm'
    17         }).state('contact', {
    18             url: '/contact',
    19             templateUrl: './components/contact/contact.tpl.html',
    20             controller: 'ContactController',
    21             controllerAs: 'vm'
    22         })
    23 
    24     }])

    controller中文件格式一直,tpl为view文件以home模块为例:

    home.controller.js

    1 angular.module('app')
    2     .controller('HomeController', HomeController);
    3 
    4 HomeController.$inject = ['$scope'];
    5 
    6 function HomeController($scope) {
    7     console.log("HomeController created successfully!!!");
    8 }

    home.tpl.html

    <h2>Page Home</h2>

    对命名做如下规定,所有文件夹都用小写,多词用点号隔开,所有文件都小写,多词用点号分割,控制器以.controller.js结尾,类似的有.service.js,.tpl.html,.directive.js,.filter.js等。

    最终运行效果如下:

    上述代码能正常运行,但是我们发现一个问题,当前js文件或者说模块较少,我们引入不会有很大的问题,但是当我们的应用变得很大,文件几十甚至上百个,如何处理呢,有人说当然使用构建工具了,一个一个引入多慢呢,构建工具当然可以做到批量引入js文件,但是我们还需要考虑按需加载的问题,举例来说,我们在打开home的时候,about和contact是没必要加载的,但是按照我们传统的模式,所有脚本都完成了加载,这首先增加了http请求次数,脚本过多的加载解析也影响浏览器的渲染,用户体验并不友好,基于此,我们有几种方式来实现,1、基于requirejs来做,这也是本章内容要讲的部分;2、使用webpack分块打包,实现按需加载,后期看时间会加入对应的文章;3、使用oclazyload(可自行google)。本文就以requirejs来实现一下业务模块的按需加载,在此之前首先引入requirejs。

    2、引入Requirejs

      RequireJS 是一个JavaScript模块加载器。它非常适合在浏览器中使用,但它也可以用在其他脚本环境,就像 Rhino and Node。使用RequireJS加载模块化脚本将提高代码的加载速度和质量,实现的是AMD规范,当然类似的还有CMD规范的实现框架seajs。

      Requirejs中,简单的说一个文件一个模块,即是单文件模块,所以对模块的加载其实本质上是对文件的加载。

      假设读者已经了解requirejs的基本使用方式。

      上一节中,讲到了提了一下controller的注册方式,其中说到了动态注册,当然除了controller之外,还有service、directive等都可以实现动态注册,这也是我们实现按需加载的基础,现在对我们的项目做一下修改,增加requirejs配置文件,main.js

     1 require.config({
     2     paths:{
     3         angular:'https://cdn.bootcss.com/angular.js/1.6.0/angular',
     4         ui_router:'https://cdn.bootcss.com/angular-ui-router/1.0.3/angular-ui-router',
     5         app:'./app'
     6        
     7     },
     8     shim:{
     9         angular:{exports:'angular'}
    10     }
    11 });
    12 
    13 require(['angular','./app','ui_router'],function(angular,app){
    14     angular.element(document).ready(function(){
    15         angular.bootstrap(document,[app.name]);
    16     })
    17 })

    app.js修改如下:

     1 define(['angular', 'ui_router'], function (angular) {
     2     var app = angular.module('app', ['ui.router'])
     3         .config(['$controllerProvider', '$provide', function ($controllerProvider, $provide) {
     4             app.register = {
     5                 controller: $controllerProvider.register,//动态注册controller
     6                 factory: $provide.factory//动态注册服务
     7             }
     8         }])
     9         .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
    10             //默认指向
    11             $urlRouterProvider.otherwise('/home');
    12 
    13             $stateProvider.state('home', {
    14                 url: '/home',
    15                 templateUrl: './components/home/home.tpl.html',
    16                 controller: 'HomeController',
    17                 controllerAs: 'vm',
    18                 resolve: {
    19                     deps: loadCtrl(['./components/home/home.controller'])
    20                 }
    21 
    22             }).state('about', {
    23                 url: '/about',
    24                 templateUrl: './components/about/about.tpl.html',
    25                 controller: 'AboutController',
    26                 controllerAs: 'vm',
    27                 resolve: {
    28                     deps: loadCtrl(['./components/about/about.controller'])
    29                 }
    30             }).state('contact', {
    31                 url: '/contact',
    32                 templateUrl: './components/contact/contact.tpl.html',
    33                 controller: 'ContactController',
    34                 controllerAs: 'vm',
    35                 resolve: {
    36                     deps: loadCtrl(['./components/contact/contact.controller'])
    37                 }
    38             })
    39 
    40         }]);
    41     return app;
    42 
    43 
    44     function loadCtrl(path_arr) {
    45         return ['$q','$rootScope', function ($q,$rootScope) {
    46             var defered = $q.defer();
    47             require(path_arr, function () {
                $rootScope.$apply(function(){
                
                  deffered.resolve();
                })
    48 49 }); 50 51 return defered.promise; 52 53 }] 54 }; 55 })

    修改controller注册方式如下:

    1 define(['app'], function (app) {
    2     app.register.controller('HomeController', HomeController);
    3 
    4     HomeController.$inject = ['$scope'];
    5 
    6     function HomeController($scope) {
    7         console.log("HomeController created successfully!!!");
    8     }
    9 })

    最后修改修改index.html中脚本引入方式,以及去掉ng-app指令启动方式,angular应用启动已在main.js中通过domready后使用脚本启动。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>demo1</title>
        <script src="https://cdn.bootcss.com/require.js/2.3.3/require.js" data-main="./main"></script>
    
    </head>
    <body>
        <div class="nav">
            <ul>
                <li><a ui-sref="home">Home</a></li>
                <li><a ui-sref="about">About</a></li>
                <li><a ui-sref="contact">Contact</a></li>
            </ul>
        </div>
        <div class="container">
            <div ui-view></div>
        </div>
    </body>
    </html>

    最终运行效果如下,可以看到只有在点击了对应的菜单时,才加载了对应的controller:

    由于代码简单,注释很少,有疑问可直接提交。

    本文到此结束。

     

     

  • 相关阅读:
    BZOJ 3744 Gty的妹子序列
    BZOJ 3872 Ant colony
    BZOJ 1087 互不侵犯
    BZOJ 1070 修车
    BZOJ 2654 tree
    BZOJ 3243 向量内积
    1003 NOIP 模拟赛Day2 城市建设
    CF865D Buy Low Sell High
    CF444A DZY Loves Physics
    Luogu 4310 绝世好题
  • 原文地址:https://www.cnblogs.com/Johnzhang/p/7197980.html
Copyright © 2011-2022 走看看