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

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