Angular 1 实现多标签页效果

背景:

我们的后台页面使用了 angular 1 + ui-router. 每点击一个页面时, 切换一个路由.

// 路由
	app.config(function($stateProvider,$urlRouterProvider,$ocLazyLoadProvider) {
		$stateProvider
		.state('welcome',{
			url: "/", // root route
			templateUrl:"view/welcome.html"
		})
		.state('admin', {
				url: '/:folder/:page',
				templateUrl : function($stateParams) {
                    return "view/"+$stateParams.folder+"/"+$stateParams.page+".html";
				},
				//cache: false,
				resolve:{
					loadMyCtrl:function($ocLazyLoad,$stateParams){
						return $ocLazyLoad.load("view/"+$stateParams.folder+"/"+$stateParams.page+"Ctrl.js");
					}
				}
		})
		$urlRouterProvider.otherwise("welcome");
	});

实现的效果如下
在这里插入图片描述

需求

原来的页面的实现是每点击一菜单,切换一个页面, 这种方式在使用上不甚方便。现要求用户界面必须为标签页方式实现, 且切换标签时页面内容无刷新,效果如下:
在这里插入图片描述

实现方案

方案一:依旧使用路由(未能满足需求)

每点击一个菜单项时新增一个页签, 页签切换时, 还是使用的 路由功能, 加载新的页面需要重新从后台获取数据.考虑过在切换页面时, 在浏览器端缓存上一页面的数据, 返回上一页面,使用缓存对页面进行渲染。此方式 需要对已有的页面功能进行改造, 代价比较高。
查阅资料,angular 高级版本有“路由重用”的概念,但是在angular 1 版本无法实现。

最终:废弃路由,使用ng-include指令

点击菜单时,相当于在窗口中同时打开多个页面,关闭页面时,使用ng-if 将页面隐藏。关键点是uib-tabset (来自于ui-bootstrap-tpls )与ng-include指令的使用,同时废弃了路由的使用。
页面效果如下:
在这里插入图片描述
主页main.html中 关键代码

 <uib-tabset active="$root.pages.active">
      <uib-tab  ng-repeat="page in pages" select="selectPage(page)" index="page.url" ng-if="!page.hide">
          <uib-tab-heading>{{page.text}}
              <button class="close tabClose"  ng-click="closePage(page,$event)">&times;</button></uib-tab-heading>
          <div class="view_body" ng-include="page.url" ></div>
      </uib-tab>
  </uib-tabset>

mainController.js中的关键代码

$rootScope.pages = [];//定义页面数组
function openPage(node){
    node.selected = true;
    $scope.curMenu = node;
    var pathinfo = node.url.split('?');
    var path =pathinfo[0];
    $ocLazyLoad.load("/admin/view/" + path + "Ctrl.js").then(() => {
        let pageUrl = "/admin/view/" + path + ".html";
        let page = $rootScope.pages.find(n => n.url == pageUrl);
        if (!page) {
            $rootScope.pages.push({text: node.text,oriUrl:node.url, url: pageUrl})
        }else{
            page.hide = false;
        }
        setTimeout(() => {
            $rootScope.pages.active = pageUrl;
            $scope.$applyAsync();
        })
    })
}
$scope.closePage = function(page,$event){
    let openedPages = $rootScope.pages.filter(n=>!n.hide);
    let index = openedPages.indexOf(page);
    if($rootScope.pages.active == page.url){
        if(openedPages.length>1){
            let toBeActivePage = index==0?openedPages[1]:openedPages[index-1];
            $rootScope.pages.active = toBeActivePage.url;
            toBeActivePage.hide = false;
        }else{
            $rootScope.pages.active = null;
        }
    }
    page.hide = true;
    $event.preventDefault();
}

实现 f5页面刷新时,自动打开上次打开页面

每次页面打开时,在当前url 加上 #开头的 页面后缀,比如http://localhost:3000/admin/main.html#/intelliDept/outwork。
然后在刷新时,根据 #后缀,跳转到指定页面。

//切换页面时,执行此方法
$scope.selectPage = function(page){
            location.hash = page.oriUrl;
 }
        
function openLastUrl(){
      let hash = location.hash ;
       if(hash && hash.indexOf("#/")==0){
           let url = hash.substr(2);
           let menu = menuData.find(n=>n.url == url)
           if(menu){
               openPage(menu);
           }
       }
   }
app.loginPromise.then(function(){
        openLastUrl();
})
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个简单的Angular构架的带有标签的网示例: app.component.html: ```html <div class="container"> <h1>标签示例</h1> <ul class="nav nav-tabs"> <li class="nav-item" *ngFor="let tab of tabs; let i = index" [class.active]="i === activeTab"> <a class="nav-link" (click)="activeTab = i">{{ tab.title }}</a> </li> </ul> <div class="tab-content"> <ng-container *ngFor="let tab of tabs; let i = index"> <div class="tab-pane" [class.active]="i === activeTab"> <h2>{{ tab.title }}</h2> <p>{{ tab.content }}</p> </div> </ng-container> </div> </div> ``` app.component.ts: ```ts import { Component } from '@angular/core'; interface Tab { title: string; content: string; } @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { tabs: Tab[] = [ { title: '标签1', content: '这是标签1的内容' }, { title: '标签2', content: '这是标签2的内容' }, { title: '标签3', content: '这是标签3的内容' }, ]; activeTab = 0; } ``` 在这个示例中,我们使用了Bootstrap的样式,并使用了ngFor指令来循环渲染标签和内容。我们定义了一个Tab接口来表示每个标签的标题和内容,然后在组件中定义了一个tabs数组来存储所有标签的信息,并使用activeTab变量来记录当前激活的标签的索引。在HTML模板中,我们使用ngFor指令循环渲染标签和内容,并通过ngClass指令动态绑定样式类。在点击标签时,我们通过(click)事件,将activeTab变量更新为当前标签的索引,从而实现切换标签的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值