使用AngularJS中的一个控制器通信两个视图

时间:2017-02-09 13:35:33

标签: javascript angularjs model-view-controller communication

我正在使用UI-Router for Angular,我为我的应用程序分隔了视图:sidebar和main。现在我需要在侧边栏视图中执行某些操作后在主视图中更改某个类。

所以,这是我的代码:

配置

.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>

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

4 个答案:

答案 0 :(得分:1)

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

的嵌套视图

答案 1 :(得分:1)

“正确”解决方案取决于主视图中导致更改导航的内容。

正如我answered here所说,如果您需要控制器相互“交谈”,这通常是一个不好的迹象。这通常意味着您应该有service来处理两个视图中要绑定的数据/状态。

但是,如果你的变化真的只是一个全球性的化妆品导航事物(我想不出一个例子,但我不想说那是不可能的),那就是“全球性的”NavigaitonController(在你的身上{例如{1}}可能是正确的。我对此表示怀疑。

所以我的建议是:考虑哪些数据导致了更改,在自己的服务中处理该数据的状态,并绑定到您需要它的服务属性。

答案 2 :(得分:0)

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

或者,你可以让控制器在更高的范围内,比如你有一个app的控制器,然后可以通过侧边栏和主页子范围继承。

答案 3 :(得分:0)

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

因为所有州的边栏应该相同。因此,如果您使用嵌套视图,则应每次都指定侧边栏。您还应该在每个州编写侧边栏代码。这不是推荐的设计应用程序的方法。

我强烈建议您完成此Q&A

然后如何设计?

将侧边栏设为简单模板,并使用ng-include渲染页脚部分。

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

正如您所看到的,侧边栏上有一个专用控制器,您不需要将代码复制到每个主控制器。