AngularJS 1.4.6 실습 1 - 단일 페이지 애플리케이션 로그인 확인

1. 멀티 뷰 라우팅 및 라우팅 네스팅

1. 멀티뷰 라우팅

목적: 로그인 페이지 보기에서 프로젝트 홈페이지 보기 분리
예:
/sigin 방문 시 로그인 페이지를 ui-view로 로드,
/ 방문 시 프로젝트 페이지를 ui-view로 로드,
기반으로 ui-view 구현 다른 경로는 다른 페이지를 로드합니다.
여기에 이미지 설명 삽입
키 코드
index.html

<div ui-view="" ></div>

app.tpl.html

<div class=app>
	<header></header>
	<div class="container-fluid-sdx">
		<div class="left-menu"></div>
		<div class="container content" ui-view="container"></div>
	</div>
</div>

routers.js

$stateProvider
.state('sigin', {
    url: 'sigin',
    templateUrl: config.tpl('sigin/sigin'),
    controllerUrl: 'ctrl/sigin/sigin',
    controller: 'sigin-sigin'
})
.state('app', {
    url: '/',
    views: {
        "@": {
            templateUrl: config.tpl('app/app')
        },
        "container@app": { // 加载content中的container视图
            templateUrl: config.tpl('search/list'),
            controllerUrl: 'ctrl/search/list',
            controller: 'search-list'
        }
    },
});

어려움: 이 프로젝트는 변경되지 않는 헤더, 왼쪽 메뉴 모음의 사이드 바 및 메뉴 모음에 따라 동적으로 변경되는 콘텐츠 컨테이너를 포함하여 고전적인 배경 관리 시스템 레이아웃을 채택합니다. 따라서 페이지의 특정 부분을 동적으로 변경하려면 라우팅 중첩을 사용해야 합니다.

2. 경로 중첩

목적: 왼쪽 메뉴바에 따라 오른쪽 콘텐츠 모듈을 동적으로 변경
예:
/search 방문 시 검색 페이지를 ui-view = "container"로 로드,
/test 방문 시 테스트 페이지를 ui-view = In으로 로드 "컨테이너";
여기에 이미지 설명 삽입
키 코드
routers.js

.state('app', {
   url: '/',
    views: {
        "@": { // 将整体布局 app.tpl.html 加载到 index.html 的 ui-view 之中
            templateUrl: config.tpl('app/app')
        },
        "container@app": { // search视图加载到app.tpl.html 中的 ui-view = "content" 之中
            templateUrl: config.tpl('search/list'),
            controllerUrl: 'ctrl/search/list',
            controller: 'search-list'
        }
    },
})
.state('app.search', {
    url: 'search',
    views: {
        "container@app": { // search视图加载到app.tpl.html 中的 ui-view = "content" 之中
            templateUrl: config.tpl('search/list'),
            controllerUrl: 'ctrl/search/list',
            controller: 'search-list'
        }
    }
})
.state('app.test', {
    url: 'test',
    views: {
        "container@app": { // test视图加载到app.tpl.html 中的 ui-view = "content" 之中
            templateUrl: config.tpl('test/index'),
            controllerUrl: 'ctrl/test/index',
            controller: 'test-index'
        }
    }
})

2. 라우팅 감지 로그인 상태

1. 경로 변경 리스너 이벤트 추가

키 코드
routers.js

// 路由改变监听事件
$rootScope.$on('$stateChangeStart', function (event, toState) {
    if (toState.name === 'sigin') {
        return;
    }

    if (angular.isUndefined($localStorage.get('user'))) {
        event.preventDefault(); // 取消默认跳转行为
        $state.go('sigin'); // 跳转到登录界面
    }
});

2. 알 수 없는 경로의 무한 루프를 해결하는 것이 매우 중요합니다.

키 코드
routers.js

$urlRouterProvider.otherwise(function ($injector) {
    var $state = $injector.get('$state');
    $state.go('app.search');
});

3. 전체 코드

1. index.html

<!DOCTYPE html>
<html>
<head>
    <title>语义搜索-管理系统</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <link href="/css/base.css" rel="stylesheet" type="text/css">
    <link href="/css/main.css" rel="stylesheet" type="text/css">
    <link href="/css/login.css" rel="stylesheet" type="text/css">
    <link href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css" rel="stylesheet">
    <link rel="shortcut icon" href="./favicon.ico" type="image/x-icon"/>
    <base href="/">
</head>
<body ng-cloak="">
<div ui-view="" class="app"></div>
<script data-main="./js/main.js?v=20180919"
        src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.min.js"></script>
</body>
</html>

2、signin.tpl.html

<div class="login-view">
    <div class="login-wrapper">
        <div class="login-box">
            <div class="login-title">
                <div class="company-name">
                    <img src="/imgs/logo.png">
                    <span>语义搜索</span>
                </div>
                <div class="systme-name">
                    <span>Snack Petty Vendor</span>
                </div>
            </div>
            <div class="login-form">
                <div class="form-group form-input">
                    <input type="text" class="normal-input" id="user-name" ng-model="username" placeholder="用户名">
                    <div class="common-error-tips">
                        <div></div>
                    </div>
                </div>
                <div class="form-group form-input">
                    <input type="password" class="normal-input" id="user-pwd" ng-model="password" placeholder="密码">
                    <div class="common-error-tips">
                        <div></div>
                    </div>
                </div>
                <div class="form-group form-btn">
                    <input type="button" class="normal-btn" ng-click="sigin()" value="登录">
                </div>
                <div class="form-group form-forget">
                    <label class="error-tips">登录失败</label>
                </div>
            </div>
        </div>
    </div>
</div>

3、app.tpl.html

<div class="app">
    <header init-navbar>
        <div class="h-banner">
            <ul class="tools">
                <li><a href="javascript:;" ng-click="logout();">退出登陆</a></li>
            </ul>
        </div>
    </header>
    <div class="container-fluid-sdx">
        <div class="left-menu">
            <ul class="menu-ul">
                <li ng-repeat="v in active.nav.list">
                    <a class="menu-ul-a" href="javascript:;" ng-click="toggle=!toggle">
                        {
   
   {v.name}} <span class="arrow"></span>
                    </a>
                    <ul class="menu-ul-ul">
                        <li ng-class="{active:active.sub_navid==l.id}" data-id="{
   
   {l.id}}"
                            ng-repeat="l in v.list" ng-show="l.hasPermission && toggle">
                            <a class="menu-ul-second" ui-sref="{
   
   {l.href}}">
                                {
   
   {l.text}}
                            </a>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
        
        <div class="container content" ui-view="container"></div>
    </div>
</div>

4.routers.js

define(['oa', 'config', 'srv/local-storage'], function (pms, config) {
    pms.run(['$state', '$stateParams', '$rootScope', '$localStorage', function ($state, $stateParams, $rootScope, $localStorage) {
        $rootScope.$state = $state;
        $rootScope.$stateParams = $stateParams;
        $rootScope.active = {};

        // 路由改变监听事件
        $rootScope.$on('$stateChangeStart', function (event, toState) {
            if (toState.name === 'sigin') {
                return;
            }

            if (angular.isUndefined($localStorage.get('user'))) {
                event.preventDefault(); // 取消默认跳转行为
                $state.go('sigin'); // 跳转到登录界面
            }
        });
    }]);
    pms.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $locationProvider) {
        // 非常重要,解决无限循环
        $urlRouterProvider.otherwise(function ($injector) {
            var $state = $injector.get('$state');
            $state.go('app.search');
        });

        $stateProvider
            .state('sigin', {
                url: 'sigin',
                templateUrl: config.tpl('sigin/sigin'),
                controllerUrl: 'ctrl/sigin/sigin',
                controller: 'sigin-sigin'
            })
            .state('app', {
                url: '/',
                views: {
                    "@": {
                        templateUrl: config.tpl('app/app')
                    },
                    "container@app": { // 加载content中的container视图
                        templateUrl: config.tpl('search/list'),
                        controllerUrl: 'ctrl/search/list',
                        controller: 'search-list'
                    }
                },
            })
            .state('app.search', {
                url: 'search',
                views: {
                    "container@app": { // app里name为container的view加载模版
                        templateUrl: config.tpl('search/list'),
                        controllerUrl: 'ctrl/search/list',
                        controller: 'search-list'
                    }
                }
            })
            .state('app.test', {
                url: 'test',
                views: {
                    "container@app": {//app里name为container的view加载模版
                        templateUrl: config.tpl('test/index'),
                        controllerUrl: 'ctrl/test/index',
                        controller: 'test-index'
                    }
                }
            })
        ;

        $locationProvider.html5Mode(true).hashPrefix('!');
    }]);
});

5、로컬 스토리지.js

define(['oa'], function (pms) {
    pms.service('$localStorage', ['$window', function ($window) {
        return {
            //读取单个属性
            set: function (key, value) {
                $window.localStorage[key] = value;
            },
            //存储对象,以JSON格式存储
            get: function (key, defaultValue) {
                return $window.localStorage[key] || defaultValue;
            },
            //读取对象
            setObject: function (key, value) {
                $window.localStorage[key] = JSON.stringify(value);//将对象以字符串保存
            },
            //获取字符串并解析成对象
            getObject: function (key) {
                return JSON.parse($window.localStorage[key] || '{}');
            },
            deleteLocalStorage: function (key) {
                return $window.localStorage.removeItem(key);
            }
        }
    }])
});

7、signin.js

define(['oa', 'config'], function (oa) {
    oa.controller('sigin-sigin', ['$rootScope', '$state', '$scope', '$localStorage', function ($rootScope, $state, $scope, $localStorage) {
        $scope.sigin = function () {
        	if (!$scope.username) {
        		alert('请输入用户名');
        	}
        	
			if(!$scope.passwod){
				alert('请输入密码');
			}
        	
        	$localStorage.set('user', {
                username: $userName.val()
            });

            $state.go('search');
        };
    }]);
});

おすすめ

転載: blog.csdn.net/qq_28413435/article/details/83895186