用AngularJS中的一个控制器交流两个视图

问题描述:

我正在使用用于Angular的UI-Router,并且为我的应用程序分隔了视图:sidebar和main。现在,我需要在侧栏视图中执行一些操作后在主视图中更改某个类。用AngularJS中的一个控制器交流两个视图

所以,这是我的代码:

配置

.state('app.area', { 
    url: '/area/:areaId', 
    views: { 
     '@': { 
      template: require('./app/generic/genericWithSidebar.html'), 
      controller: 'AreaCtrl' 
     }, 
     '[email protected]': { 
      template: require('./app/area/_area.html'), 
      controller: 'AreaCtrl', 
      controllerAs: 'CTRL', 
     }, 
     '[email protected]': { 
      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> 

我需要在视图之间进行通信,而不是控制器,我有一个控制器。

+0

需要注意的是,每个视图初始化一个新的'AreaCtrl'实例,每个实例都有它自己的作用域 – charlietfl

+0

@charlietfl那么,我该怎么做?我应该删除控制器定义的视图,只留下父母? – Lukas

+0

可能.....是。虽然 – charlietfl

“正确”的解决方案嵌套视图取决于它是什么改变了,导致在导航的改变你的主要观点。

因为我只是answered here,如果你需要控制器互相“交谈”,这通常是一个不好的迹象。这通常意味着您应该有一个service,负责在两个视图中处理要绑定的数据/状态。如果你的变化真的只是一个全球化妆品导航的东西(我想不出一个例子,但我不想说这是不可能的),但是一个“全球”NavigaitonController(例如你的body)可能是正确的。但我对此表示怀疑。

所以我的建议是:想想什么样的数据导致了这个变化,在它自己的服务中处理这些数据的状态并绑定到你需要它的服务属性。

+0

所以,这可以确定我用了一个,其他控制器在侧边栏中的行动?在这种情况下,一切工作正常。 Thx从顶部的建议。 – Lukas

您可以在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-routerdocs

+0

不,我没有访问控制器的意见:( – Lukas

+0

你是怎么说的?:) –

+0

简单,动作形式控制器没有传播,我在主视图中使用它的工作正常... – Lukas

状态意味着被服务封装,所以实际上,如果你有应该在应用程序之间共享的状态,你应该创建一个服务。

或者,您可以将控制器放在更高的范围内,例如您拥有应用程序的控制器,然后可以通过侧栏和主页子范围继承控制器。

也许这个答案并不是您的特定问题的确切答案。但是从架构的角度来看,您不应该使用嵌套视图来通过侧边栏来处理主视图。

因为这个侧边栏对于所有状态应该是相同的。所以如果你使用嵌套视图,你应该每次都指定你的侧边栏。你也应该在每个州编写侧边栏的代码。这不是设计您的应用程序的推荐方式。

我强烈建议你通过这个Q&A

那么如何设计?

使您的边栏成为一个简单的模板,并使用ng-include来渲染页脚部分。

<footer ng-include="'/sidebar.html'" ng-controller="sidebarController"></footer> 

正如你可以看到有你的侧边栏的专用控制器,你不必重复你的代码添加到每个主控制器。

+1

不,侧栏对于不同的页面会有所不同,所以我需要为它和主要部分分隔子视图。 – Lukas

+0

@Lukas好吧,如果情况是这样的,那么使用嵌套视图。 –