下拉和路线问题

时间:2016-06-06 18:46:35

标签: angularjs

我在angularJS中有一个来自JSON数据的动态填充导航栏。

我在导航栏中有六个来自JSON数据的标签:

  • 现在当我按下第一个标签时,会有一个1st.html文件加载到div。这是使用ngRoute完成的。
  • 第二个标签和第三个标签的工作方式类似于按预期工作。第四个标签是下拉列表。
  • 在第4个选项卡上:显示悬停下拉列表,但是当在下拉列表后面点击时,由于重定向路由选项,路由将被定向到主页。如果导航类似于第3个选项卡,则用户单击第4个选项卡,应显示下拉列表,活动类应为第3个选项卡容器。

请帮忙。感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

我认为让它工作的唯一技巧是你必须手动引导AngularJS,因为你需要在配置阶段之前加载数据。

您可以在domready处理程序中执行ajax请求,以加载路由数据并将其添加到成功回调中的Angular配置中。 然后,您可以通过调用angular.bootstrap来引导应用程序。 (需要html标记中没有ng-app。)

routesJson的结构是让它工作所需的最小值。下拉路线没有嵌套路线。 (但我认为没关系。)

您可以使用routesJson创建带有ng-repeat的html标记,并将其用于ngRoute配置。我已经将它添加到服务中,因此更容易访问全局变量。 (在演示的第一个版本中,我开始使用注释的var routesJson = [{}]全局。)

下面的演示或此jsfiddle中的内容应该是您正在寻找的内容。

/*var routesJson = [{
	id: 0,
    name: 'home',
    url: '/',
    templateUrl: 'home.html',
    caption: 'Home',
    controllerAs: 'homeCtrl',
    controller: function($scope) {
    	$scope.hello = 'hello from homeCtrl scope';
        this.hello = 'hello from homeCtrl';
    }
},
{
	id: 1,
    name: 'first',
    url: '/first/',
    templateUrl: '1st.html',
    caption: '1st item'
},
{
	id: 2,
    name: 'dropdown',
    caption: 'Dropdown',
    nested: [{
    	id: 0,
        url: '/dashboard/',
        name: 'dashboard',
        caption: 'Dashboard',
        templateUrl: 'dashboard.html'
    }]
}];*/

angular.module('demoApp', ['ngRoute', 'ui.bootstrap'])
	.provider('routesData', function() {
    	var routesData = [];
        
        this.setRoutes = function(routes) {
        	routesData = routes;
        }
        
    	this.$get = function() {
        	return new RoutesDataService(routesData);
        }
    })
	.controller('mainController', MainController);
    
angular.element(document).ready(function () {
	// loading json config on dom ready and manually bootstrap angular
	$.ajax({
        url: "https://www.mocky.io/v2/5755df7b1300004f318ea48b",

        // The name of the callback parameter, as specified by the YQL service
        jsonp: "callback",

        // Tell jQuery we're expecting JSONP
        dataType: "jsonp",
        success: function(jsonData) {
            var routesJson = jsonData;
            
            angular.module('demoApp')
            	.config(routesConfig);

			function routesConfig($routeProvider, routesDataProvider) {
                var url, templateUrl, route;
                //console.log('add config', $routeProvider);
                //console.log('routes', routesJson);
                // add the routes to routesData service
                routesDataProvider.setRoutes(routesJson);
                
                // load routes to $routeProvider
                loadRoutes(routesJson);

                function addRoute(url, route) {
                    $routeProvider.when(url, {
                        templateUrl: route.templateUrl,
                        controller: route.controller,
                        controllerAs: route.controllerAs
                    });
                }

                function loadRoutes(routes) {
                    for (var i=0; i < routes.length; i++) {
                        route = routes[i];
                        url = route.url;
                        if (!route.nested) {
                            templateUrl = route.templateUrl;
                            if ( url ) {
                                addRoute(url, route);
                            }
                        } else {
                            //console.log('nested')
                            // nested route or only a dropdown route
                            // --> no nesting in the demo just top-level routes
                            var nestedRoute;
                            for(var j=0; j<route.nested.length; j++) {
                                nestedRoute = route.nested[j];
                                addRoute(nestedRoute.url, nestedRoute);
                            }
                        }
                    }

                    $routeProvider.otherwise({
                        redirectTo: "/"
                    });
                }
            }

            // manual bootstrapping
            //setTimeout(function() { 
            // add timeout for testing loading spinner
            angular.bootstrap(document, ['demoApp']);
            //}, 4000);
        }
    });
});

function RoutesDataService(routes) {
	var factory = {
    	routes: [] // we could add defaults here
    };
    
    angular.extend(factory, {
    	routes: routes
    });
    
    return factory;
}

function MainController($location, $http, routesData) {
	var vm = this;
    vm.loaded = true;
    vm.routesJson = routesData.routes;
    vm.isActive = function(url) {
    	return ($location.url() === url);
    };   	
}
.nav .btn {
    /* fix paddin in tab nav*/
    padding: 10px 15px;
}

/* spinner css created with
http://cssload.net/en/spinners/8 */

.wrapper {
	padding-left: 1em;
	padding-right: 1em;
	margin: auto;
	display: block;
	width: 195px;
}

.cssload-loader {
	width: 49px;
	height: 49px;
	border-radius: 50%;
	margin: 3em;
	display: inline-block;
	position: relative;
	vertical-align: middle;
}

.cssload-loader {
	width: 49px;
	height: 49px;
	border-radius: 50%;
	margin: 3em;
	display: inline-block;
	position: relative;
	vertical-align: middle;
}
.cssload-loader,
.cssload-loader:before,
.cssload-loader:after {
	animation: 1.15s infinite ease-in-out;
		-o-animation: 1.15s infinite ease-in-out;
		-ms-animation: 1.15s infinite ease-in-out;
		-webkit-animation: 1.15s infinite ease-in-out;
		-moz-animation: 1.15s infinite ease-in-out;
}
.cssload-loader:before,
.cssload-loader:after {
	width: 100%; 
	height: 100%;
	border-radius: 50%;
	position: absolute;
	top: 0;
	left: 0;
}

.cssload-loader:before,
.cssload-loader:after {
		content: "";
}

.cssload-loader:before,
.cssload-loader:after {
		content: "";
		background-color: rgb(0,0,0);
		transform: scale(0);
		-o-transform: scale(0);
		-ms-transform: scale(0);
		-webkit-transform: scale(0);
		-moz-transform: scale(0);
		animation: cssload-animation 1.73s infinite ease-in-out;
		-o-animation: cssload-animation 1.73s infinite ease-in-out;
		-ms-animation: cssload-animation 1.73s infinite ease-in-out;
		-webkit-animation: cssload-animation 1.73s infinite ease-in-out;
		-moz-animation: cssload-animation 1.73s infinite ease-in-out;
}
.cssload-loader:after { animation-delay: 0.86s;
		-o-animation-delay: 0.86s;
		-ms-animation-delay: 0.86s;
		-webkit-animation-delay: 0.86s;
		-moz-animation-delay: 0.86s; }



@keyframes cssload-animation {
	0%	 { transform: translateX(-100%) scale(0); }
	50%	{ transform: translateX(0%)		scale(1); }
	100% { transform: translateX(100%)	scale(0); }
}

@-o-keyframes cssload-animation {
	0%	 { -o-transform: translateX(-100%) scale(0); }
	50%	{ -o-transform: translateX(0%)		scale(1); }
	100% { -o-transform: translateX(100%)	scale(0); }
}

@-ms-keyframes cssload-animation {
	0%	 { -ms-transform: translateX(-100%) scale(0); }
	50%	{ -ms-transform: translateX(0%)		scale(1); }
	100% { -ms-transform: translateX(100%)	scale(0); }
}

@-webkit-keyframes cssload-animation {
	0%	 { -webkit-transform: translateX(-100%) scale(0); }
	50%	{ -webkit-transform: translateX(0%)		scale(1); }
	100% { -webkit-transform: translateX(100%)	scale(0); }
}

@-moz-keyframes cssload-animation {
	0%	 { -moz-transform: translateX(-100%) scale(0); }
	50%	{ -moz-transform: translateX(0%)		scale(1); }
	100% { -moz-transform: translateX(100%)	scale(0); }
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.3/ui-bootstrap-tpls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular-route.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div id="app" ng-controller="mainController as mainCtrl">
    <div class="wrapper" ng-hide="mainCtrl.loaded">
        <div class="cssload-loader"></div>
    </div>
    <div ng-cloak>
        <ul class="nav nav-tabs">
            <li ng-class="{active: mainCtrl.isActive(navItem.url)}"ng-repeat="navItem in mainCtrl.routesJson">
                <a ng-href="#{{navItem.url}}" ng-if="!navItem.nested">{{navItem.caption}}</a>
                <div class="btn-group" uib-dropdown ng-if="navItem.nested">
                    <a class="btn btn-default" uib-dropdown-toggle>
                    {{navItem.caption}}<span class="caret"></span>
                    </a>
                    <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="single-button">
                        <li role="menuitem" ng-class="{active: mainCtrl.isActive(subNav.url)}" ng-repeat="subNav in navItem.nested"><a ng-href="#{{subNav.url}}">{{subNav.caption}}</a></li>
                      </ul>
                </div>
            </li>
          <!--<li class="active"><a href="#">Home</a></li>
          <li><a href="#">Menu 1</a></li>
          <li><a href="#">Menu 2</a></li>
          <li><a href="#">Menu 3</a></li>-->
        </ul>
      <div class="container">
          <div ng-view></div>
      </div>
  </div>
    
  <script type="text/ng-template" id="home.html">
  	<h1>home</h1>
    {{hello}}<br/>
    {{homeCtrl.hello}}<br/>
    <a href="#/dashboard">dashboard</a>
  </script>
  <script type="text/ng-template" id="1st.html">
  	<h1>first</h1>
  </script>
  <script type="text/ng-template" id="dashboard.html">
  	<h1>dashboard</h1>
  </script>
</div>

答案 1 :(得分:0)

我在这里使用了ngx-bootstrap,您可以删除#切换链接,原因是它将被视为链接

<ul *ngIf="loggedIn()" class="nav navbar-nav navbar-right">        
        <li class="dropdown" dropdown>
        **// remove href**
          <a href="#" class="dropdown-toggle" dropdownToggle >
            Welcome {{_authService.decodeToken?.unique_name | titlecase}}
            <span class="caret"></span>
          </a>
          <ul class="dropdown-menu" *dropdownMenu>
            <li><a href="#"><i class="fa fa-user"></i> Profile</a></li>           
            <li role="separator" class="divider"></li>
            <li><a (click)="logout()"><i class="fa fa-sign-out"></i> Logout</a></li>
          </ul>
        </li>
      </ul>

或者您可以将点击事件添加为假

 <li (click) = "false" class="dropdown" dropdown>
          <a class="dropdown-toggle" dropdownToggle >
            Welcome {{_authService.decodeToken?.unique_name | titlecase}}
            <span class="caret"></span>
          </a>
          <ul class="dropdown-menu" *dropdownMenu>
            <li><a href="#"><i class="fa fa-user"></i> Profile</a></li>           
            <li role="separator" class="divider"></li>
            <li><a (click)="logout()"><i class="fa fa-sign-out"></i> Logout</a></li>
          </ul>
        </li>