在 AngularJS 中与一个控制器通信两个视图
Communicate two views with one controller in AngularJS
我正在为 Angular 使用 UI-Router,并且我为我的应用程序分离了视图:侧边栏和主视图。现在我需要在侧边栏视图中执行一些操作后更改主视图中的一些 class。
所以,这是我的代码:
配置
.state('app.area', {
url: '/area/:areaId',
views: {
'@': {
template: require('./app/generic/genericWithSidebar.html'),
controller: 'AreaCtrl'
},
'main@app.area': {
template: require('./app/area/_area.html'),
controller: 'AreaCtrl',
controllerAs: 'CTRL',
},
'sidebar@app.area': {
template: require('./app/area/_sidebar.html'),
controller: 'AreaCtrl',
controllerAs: 'CTRL',
}
},
控制器
class AreaCtrl {
constructor($scope) {
"ngInject";
this.$scope = $scope;
this.$scope.descriptionIsActive = false;
}
showAreaDescription() {
this.$scope.descriptionIsActive = !this.$scope.descriptionIsActive;
}
}
export default AreaCtrl;
侧边栏和主视图
// sidebar view
<span ng-click="CTRL.showAreaDescription()">show more</span>
// main view
<div ng-class="{'active': CTRL.descriptionIsActive}"></div>
我需要在视图之间进行通信,而不是控制器,我只有一个控制器。
您可以在 views
选项之外定义您的控制器,这样它只会在状态加载时加载一次。
stateProvider.state("app.area",{
url:'/app.area',
templateUrl: 'app_area_frame.html',
controller:'AreaCtrl',
controllerAs: 'CTRL',
views:{
'main':{
template: require('./app/area/_area.html')
},
'sidebar':{
template: require('./app/area/_sidebar.html')
}
}
})
UI-router
docs
的嵌套视图
"correct" 解决方案取决于主视图中导致导航发生变化的内容。
正如我刚刚 ,如果您需要控制器相互 "talk",这通常是一个不好的迹象。这通常意味着您应该有一个 service
来处理您要在两个视图中绑定的 data/state。
但是,如果您的更改真的只是全局装饰性导航(我想不出一个例子,但我不想说那是不可能的),"global" NavigaitonController
(例如,在您的 body
上)可能是正确的。不过我对此表示怀疑。
所以我的建议是:考虑是什么数据引起了变化,在它自己的服务中处理该数据的状态,并在需要的地方绑定到该服务属性。
状态应该被服务封装,所以事实上,如果你有状态应该在应用程序之间共享,你应该创建一个服务。
或者,你可以在更高的范围内有一个控制器,假设你有一个应用程序的控制器,然后它可以被侧边栏和主页子范围继承。
也许这个答案不是您特定问题的确切答案。但是从架构的角度来看,您不应该使用嵌套视图来处理带有侧边栏的主视图。
因为这个边栏对于所有州来说应该是一样的。因此,如果您使用嵌套视图,则每次都应指定侧边栏。您还应该在每个州编写侧边栏代码。这不是设计应用程序的推荐方法。
我强烈建议你完成这个 。
那怎么设计呢?
将侧边栏作为简单模板并使用 ng-include 呈现页脚部分。
<footer ng-include="'/sidebar.html'" ng-controller="sidebarController"></footer>
如您所见,您的边栏有一个专用控制器,您不需要将代码复制到每个主控制器。
我正在为 Angular 使用 UI-Router,并且我为我的应用程序分离了视图:侧边栏和主视图。现在我需要在侧边栏视图中执行一些操作后更改主视图中的一些 class。
所以,这是我的代码:
配置
.state('app.area', {
url: '/area/:areaId',
views: {
'@': {
template: require('./app/generic/genericWithSidebar.html'),
controller: 'AreaCtrl'
},
'main@app.area': {
template: require('./app/area/_area.html'),
controller: 'AreaCtrl',
controllerAs: 'CTRL',
},
'sidebar@app.area': {
template: require('./app/area/_sidebar.html'),
controller: 'AreaCtrl',
controllerAs: 'CTRL',
}
},
控制器
class AreaCtrl {
constructor($scope) {
"ngInject";
this.$scope = $scope;
this.$scope.descriptionIsActive = false;
}
showAreaDescription() {
this.$scope.descriptionIsActive = !this.$scope.descriptionIsActive;
}
}
export default AreaCtrl;
侧边栏和主视图
// sidebar view
<span ng-click="CTRL.showAreaDescription()">show more</span>
// main view
<div ng-class="{'active': CTRL.descriptionIsActive}"></div>
我需要在视图之间进行通信,而不是控制器,我只有一个控制器。
您可以在 views
选项之外定义您的控制器,这样它只会在状态加载时加载一次。
stateProvider.state("app.area",{
url:'/app.area',
templateUrl: 'app_area_frame.html',
controller:'AreaCtrl',
controllerAs: 'CTRL',
views:{
'main':{
template: require('./app/area/_area.html')
},
'sidebar':{
template: require('./app/area/_sidebar.html')
}
}
})
UI-router
docs
"correct" 解决方案取决于主视图中导致导航发生变化的内容。
正如我刚刚 service
来处理您要在两个视图中绑定的 data/state。
但是,如果您的更改真的只是全局装饰性导航(我想不出一个例子,但我不想说那是不可能的),"global" NavigaitonController
(例如,在您的 body
上)可能是正确的。不过我对此表示怀疑。
所以我的建议是:考虑是什么数据引起了变化,在它自己的服务中处理该数据的状态,并在需要的地方绑定到该服务属性。
状态应该被服务封装,所以事实上,如果你有状态应该在应用程序之间共享,你应该创建一个服务。
或者,你可以在更高的范围内有一个控制器,假设你有一个应用程序的控制器,然后它可以被侧边栏和主页子范围继承。
也许这个答案不是您特定问题的确切答案。但是从架构的角度来看,您不应该使用嵌套视图来处理带有侧边栏的主视图。
因为这个边栏对于所有州来说应该是一样的。因此,如果您使用嵌套视图,则每次都应指定侧边栏。您还应该在每个州编写侧边栏代码。这不是设计应用程序的推荐方法。
我强烈建议你完成这个
那怎么设计呢?
将侧边栏作为简单模板并使用 ng-include 呈现页脚部分。
<footer ng-include="'/sidebar.html'" ng-controller="sidebarController"></footer>
如您所见,您的边栏有一个专用控制器,您不需要将代码复制到每个主控制器。