【问题标题】:Access parent controller from sub ui-view component从子 ui-view 组件访问父控制器
【发布时间】:2018-04-02 23:57:34
【问题描述】:

我似乎在这个问题上找不到答案,我尝试过使用 require,但没有运气它无法从组件定义中找到“设置”父级。

我希望所有“子”路由都可以访问所有“设置”方法,这样我就可以跨多个状态重复使用方法。

如何从嵌套的 ui-view 组件访问“设置”组件控制器上的方法?

index.html

<ui-view></ui-view>

app.js

$stateProvider.register('settings', {
    abstract : true,
    component: 'settings',
    url : '/settings'
});
$stateProvider.register('settings.user', {
    component: 'settingsUser',
    url : '/:user',
});

angular.module('app', [])
    .component('settings', {
        template : `<ui-view></ui-view>`,
        controller : class Settings {
            constructor($state) {
                this.test = () => console.log('test');
                $state.go('settings.user');
            }

        }
    })
    .component('settingsUser', {
         controller : class SettingsUser {
             constructor() {
                 // want to access parent controller methods
             }
         }
    });

【问题讨论】:

    标签: angularjs angular-ui-router components


    【解决方案1】:

    答案其实很简单,只是没想到它可以和路由一起工作,有了子视图,你可以简单地通过require block 请求父组件。这会在子视图的控制器中公开 $onInit 生命周期阶段所需组件的控制器。

    $stateProvider.register('settings', {
        abstract : true,
        component: 'settings',
        url : '/settings'
    });
    $stateProvider.register('settings.user', {
        component: 'settingsUser',
        url : '/:user',
    });
    
    angular.module('app', [])
        .component('settings', {
            template : `<ui-view></ui-view>`,
            controller : class Settings {
                constructor($state) {
                    this.test = () => console.log('test');
                    $state.go('settings.user');
                }
    
            }
        })
        .component('settingsUser', {
             require : {
                 $settings : '^settings'
             },
             controller : class SettingsUser {
                 constructor() {
                     // want to access parent controller methods
                 }
                 $onInit() {
                     this.$settings.test()
                 }
             }
        });
    

    【讨论】:

    • 但是在这个例子中,你需要所有的控制器,而不仅仅是一个范围
    • 这告诉我你不了解控制器和组件,而且我一次也没有提到范围,我提到了控制器。控制器是单个实例,并且(在组件中)和隔离范围,所以它就是这样做的。
    【解决方案2】:

    您可以使用$rootScope 而不是$scope 访问它,以满足您的访问需求。 在此示例中,test1$rootscope,但 test2$scope,在 controller Ctrl2 中我们更改了 test1,它将在 Ctrl1 中更改,请参见示例:

    var app = angular.module('myApp', []);
    app.controller('Ctrl1', function($scope,$rootScope) {
        $rootScope.test1 = "topController";
        $scope.test2 = "topController2";
    })
    .controller('Ctrl2', function($scope,$rootScope) {
        $rootScope.test1 = "mainController";
        $scope.test2 = "mainController2";
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="myApp" >
      <div ng-controller="Ctrl1">
      {{test1}} {{test2}}
      </div>
      <div ng-controller="Ctrl2">
      {{test1}} {{test2}}
      </div>
    </div>

    【讨论】:

    • 这没有意义?
    • $rootScope 是一个全局范围
    • 这违背了所有 Angular 原则......我发现了一个更好的由 Angular 团队推广的解决方案,我已经在这里发布了
    • 请分享您的解决方案
    • 我刚刚发布了
    猜你喜欢
    • 2018-01-16
    • 1970-01-01
    • 2020-04-16
    • 2018-11-15
    • 1970-01-01
    • 2014-02-22
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多