如何在 Angular 中使用 UI Router 正确实现多个视图?
How to correctly implement multiple views with UI Router in Angular?
我正在尝试实现一个包含两个主要内容的网站 'panes'(假设两列各占页面宽度的一半)。窗格应该能够相互独立地更改并拥有自己的控制器并且能够在彼此之间传递数据(因此用户可以在左窗格中浏览一堆页面,而右窗格保持不变而无需重新加载和反之亦然,左窗格中的更改可以更新右窗格中显示的数据)。
我在 UI 路由器上浏览了一堆 examples/tutorials,但似乎找不到一个很好的例子来说明如何实现我正在尝试做的事情。所有这些似乎都显示了单个嵌套视图的示例(因此较大视图中的单个视图)或显示多个视图,但没有显示如何更改彼此独立的视图。
我想用 index.html 文件中的单个 <div ui-view></div>
来执行此操作(而不是多个 ui-views),这样我就可以在单亲 ui-查看并且不在 index.html 文件中。
现在我有类似下面的 js 文件:
config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
views: {
'': { templateUrl: 'views/home.html' },
'left@home': {
templateUrl: 'views/charting/chartHome.html',
},
'right@home': {
templateUrl: 'views/view1.html',
controller: 'View1Ctrl'
}
}
});
}]);
以及 home.html 的以下 HTML:
<div>
<h1>This is home</h1>
</div>
<div ui-view='left'>
</div>
<div ui-view='right'>
</div>
有人可以帮忙吗?或者这是对网站的错误思考方式?如果是这样我应该做什么?
谢谢!
使用 ui-router 解决这个问题相当复杂。
我创建这个 fiddle 来尝试 ui-router 嵌套状态。
它有效,但它越来越难看 quickly。
它是这样工作的:home.main.left
route 仅更改左视图并使用来自 home.main
的右视图。最好让两个视图状态彼此独立,但我不确定如何使用 ui-router 做到这一点。
我认为最好使用 ui-router 来完成左侧部分的导航,并为右侧部分使用自定义指令(或相反)。要与指令通信,您可以使用 $emit/$broadcast
.
也可以通过带有链接 ui-sref
或 $state.go(...)
方法的指令更改左侧部分的路线。
请查看下面或此 jsfiddle 中的演示。
angular.module('demoApp', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
templateUrl: 'views/home.html',
abstract: true
})
.state('home.main', {
url: '/home',
templateUrl: 'views/charting/chartHome.html',
controller: 'LeftCtrl'
})
.state('home.left', {
template: 'home.left <a href="#" ui-sref="home.left1">left1 change</a><br/>{{hello}}',
controller: 'LeftCtrl'
})
.state('home.left1', {
template: 'home.left1 <a href="#" ui-sref="home.left2">left2 change</a>'
})
.state('home.left2', {
template: 'home.left2 <a href="#" ng-click="triggerDirective()">change directive</a>',
controller: function($scope) {
$scope.triggerDirective = function() {
console.log('do directive action');
$scope.$emit('rightContent:changeMsg', 'new content');
// emit to rootscope because rightcontent is not a child of leftcontent
};
}
})
}])
.directive('rightContent', function() {
return {
restrict: 'EA',
template: 'Some static content or other stuff from directive. <strong>{{message}}</strong>',
controller: function($scope, $rootScope) {
$scope.message = 'hello from directive.';
$rootScope.$on('rightContent:changeMsg', function(evt, message) {
console.log(message);
$scope.message = message;
});
}
}
})
.controller('LeftCtrl', function($scope){
$scope.hello = 'hello from left';
})
.controller('appController', function($scope) {
});
.left {
float: left;
width: 50%;
height: 200px;
background: lightgreen;
}
.right {
float: right;
width: 50%;
height: 200px;
background: lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<div ng-app="demoApp" ng-controller="appController">
<script type="text/ng-template" id="views/home.html">
<div>
<h1>This is home</h1>
</div>
<div class="wrapper">
<div ui-view="" class="left">
</div>
<div class="right">
<right-content></right-content>
</div>
<a href="#" ui-sref="home.main">home</a>
</div>
</script>
<script type="text/ng-template" id="views/charting/chartHome.html">
left {{hello}}
<a href="#" ui-sref="home.left">left change</a>
</script>
<script type="text/ng-template" id="views/view1.html">
right {{hello}}
</script>
<div ui-view=""></div>
</div>
我正在尝试实现一个包含两个主要内容的网站 'panes'(假设两列各占页面宽度的一半)。窗格应该能够相互独立地更改并拥有自己的控制器并且能够在彼此之间传递数据(因此用户可以在左窗格中浏览一堆页面,而右窗格保持不变而无需重新加载和反之亦然,左窗格中的更改可以更新右窗格中显示的数据)。
我在 UI 路由器上浏览了一堆 examples/tutorials,但似乎找不到一个很好的例子来说明如何实现我正在尝试做的事情。所有这些似乎都显示了单个嵌套视图的示例(因此较大视图中的单个视图)或显示多个视图,但没有显示如何更改彼此独立的视图。
我想用 index.html 文件中的单个 <div ui-view></div>
来执行此操作(而不是多个 ui-views),这样我就可以在单亲 ui-查看并且不在 index.html 文件中。
现在我有类似下面的 js 文件:
config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
views: {
'': { templateUrl: 'views/home.html' },
'left@home': {
templateUrl: 'views/charting/chartHome.html',
},
'right@home': {
templateUrl: 'views/view1.html',
controller: 'View1Ctrl'
}
}
});
}]);
以及 home.html 的以下 HTML:
<div>
<h1>This is home</h1>
</div>
<div ui-view='left'>
</div>
<div ui-view='right'>
</div>
有人可以帮忙吗?或者这是对网站的错误思考方式?如果是这样我应该做什么?
谢谢!
使用 ui-router 解决这个问题相当复杂。
我创建这个 fiddle 来尝试 ui-router 嵌套状态。 它有效,但它越来越难看 quickly。
它是这样工作的:home.main.left
route 仅更改左视图并使用来自 home.main
的右视图。最好让两个视图状态彼此独立,但我不确定如何使用 ui-router 做到这一点。
我认为最好使用 ui-router 来完成左侧部分的导航,并为右侧部分使用自定义指令(或相反)。要与指令通信,您可以使用 $emit/$broadcast
.
也可以通过带有链接 ui-sref
或 $state.go(...)
方法的指令更改左侧部分的路线。
请查看下面或此 jsfiddle 中的演示。
angular.module('demoApp', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
templateUrl: 'views/home.html',
abstract: true
})
.state('home.main', {
url: '/home',
templateUrl: 'views/charting/chartHome.html',
controller: 'LeftCtrl'
})
.state('home.left', {
template: 'home.left <a href="#" ui-sref="home.left1">left1 change</a><br/>{{hello}}',
controller: 'LeftCtrl'
})
.state('home.left1', {
template: 'home.left1 <a href="#" ui-sref="home.left2">left2 change</a>'
})
.state('home.left2', {
template: 'home.left2 <a href="#" ng-click="triggerDirective()">change directive</a>',
controller: function($scope) {
$scope.triggerDirective = function() {
console.log('do directive action');
$scope.$emit('rightContent:changeMsg', 'new content');
// emit to rootscope because rightcontent is not a child of leftcontent
};
}
})
}])
.directive('rightContent', function() {
return {
restrict: 'EA',
template: 'Some static content or other stuff from directive. <strong>{{message}}</strong>',
controller: function($scope, $rootScope) {
$scope.message = 'hello from directive.';
$rootScope.$on('rightContent:changeMsg', function(evt, message) {
console.log(message);
$scope.message = message;
});
}
}
})
.controller('LeftCtrl', function($scope){
$scope.hello = 'hello from left';
})
.controller('appController', function($scope) {
});
.left {
float: left;
width: 50%;
height: 200px;
background: lightgreen;
}
.right {
float: right;
width: 50%;
height: 200px;
background: lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<div ng-app="demoApp" ng-controller="appController">
<script type="text/ng-template" id="views/home.html">
<div>
<h1>This is home</h1>
</div>
<div class="wrapper">
<div ui-view="" class="left">
</div>
<div class="right">
<right-content></right-content>
</div>
<a href="#" ui-sref="home.main">home</a>
</div>
</script>
<script type="text/ng-template" id="views/charting/chartHome.html">
left {{hello}}
<a href="#" ui-sref="home.left">left change</a>
</script>
<script type="text/ng-template" id="views/view1.html">
right {{hello}}
</script>
<div ui-view=""></div>
</div>