简体   繁体   English

如何:AngularJS - 从子控制器访问父控制器中的方法

[英]How To: AngularJS - Access method in parent controller from child controller

I have an AngularJs page with tabs in the UI.我在 UI 中有一个带有选项卡的 AngularJs 页面。 Each tab loads different data.每个选项卡加载不同的数据。 One of these is a list of tasks for a user.其中之一是用户的任务列表。 The user can search on this tab for various tasks, and when they find one, they can click on it, and it will bring up an edit form for that task on another tab.用户可以在这个选项卡上搜索各种任务,当他们找到一个任务时,他们可以点击它,它会在另一个选项卡上显示该任务的编辑表单。

I can't figure out how to show that other tab, since the tab selection resides in the parent controller (the main page), and the tabs all have their own child controllers.我不知道如何显示其他选项卡,因为选项卡选择驻留在父控制器(主页)中,并且选项卡都有自己的子控制器。

Parent controller:父控制器:

"use strict";

angular
.module("userTasks.controllers", [])

.controller("UserTasksCtrl",
    ["$scope", "$window", "$uibModal", "$filter", "$location", "$routeParams", "api",
    function($scope, $window, $uibModal, $filter, $location, $routeParams, api) {
        var vm = this;
        vm.activeTab = "Tasks";

        vm.loadTaskList = (
            function() {
                vm.pageTaskList = "/Content/UserTasks/taskList.html";
            }
        );

        vm.loadAddEditTask = (
            function() {
                vm.pageAddEditTask = "/Content/UserTasks/tasksAddEdit.html";
            }
        );

        vm.doTabRouting = (
            function() {
                switch (vm.activeTab) {
                    case "Tasks":
                        vm.tabTasks = true;
                        vm.loadTasks();
                        break;
                    case "CreateTask":
                        vm.tabAddEditTask = true;
                        vm.loadAddEditTask();
                        break;
                    default:
                        vm.tabDetails = true;
                        vm.loadDetails();
                        break;
                }
            }
        );
    }
]);

Child controler:儿童控制器:

"use strict";

angular
.module("userTasks.controllers_Tasks", [])

.controller("TasksCtrl",
    ["$scope", "$routeParams", "$filter", "$uibModal", "$uibModalStack", "taskAPI",
    function ($scope, $routeParams, $filter, $uibModal, $uibModalStack, taskAPI) {
        var vm = this;

        vm.openTaskAddEdit = (
            function(task) {
                vm.root.task= {
                    Id: task.Id
                };

                vm.root.tabTasks        = false;
                vm.root.tabAddEditTask  = true;

                vm.root.activeTab       = "CreateTask";
                vm.root.pageAddEditJob  = "/Content/UserTasks/taskAddEdit.html";
                vm.root.tab             = "CreateTask";
            }
        );
    }
]);

The index.html (parent page) with the tabs:带有标签的 index.html(父页面):

    <!-- Tabs for Nav -->
    <ul class="nav nav-tabs">
        <li class="nav-item" id="headingTasks" ng-class="{ 'active': vm.tabTasks }">
            <a data-target="#tabTasks" data-toggle="tab" class="nav-link pt-1 pr-2 pb-1 pl-2"
               ng-class="{ 'active': vm.tabTasks }"
               ng-click="vm.loadTasks()">Tasks</a>
        </li>
        <li class="nav-item" id="headingAddEditTask" ng-class="{ 'active': vm.tabAddEditTasks }" ng-if="vm.tabAddEditTasks">
            <a data-target="#tabAddEditTasks" data-toggle="tab" class="nav-link pt-1 pr-2 pb-1 pl-2"
               ng-class="{ 'active': vm.tabAddEditTasks }">{{vm.addEditText}} <span ng-if="(vm.addEditUnsaved)" style="font-size: 85%;"><i class="fa fa-fw fa-warning text-warning"></i></span></a>
        </li>
    </ul>

    <!-- Tabs content -->
    <div class="tab-content">
        <!--Tasks-->
        <div id="tabTasks" class="tab-pane fade show tab-pane-bordered" ng-class="{ 'active show': vm.tabTasks}">
            <div class="row p-1 m-0">
                <div class="col-12 p-0 m-0">
                    <div ng-include="vm.pageTasks"></div>
                </div>
            </div>
        </div>

        <!--Add/Edit Task-->
        <div id="tabAddEditTasks" class="tab-pane fade show tab-pane-bordered" ng-class="{ 'active show': vm.tabAddEditTasks }">
            <div class="row p-1 m-0">
                <div class="col-12 p-0 m-0">
                    <div ng-include="vm.pageAddEditTask"></div>
                </div>
            </div>
        </div>
    </div>

I want to be able to call vm.openTaskAddEdit(task) from the task list tab, and have it open the task add/edit tab and load that data.我希望能够从任务列表选项卡调用vm.openTaskAddEdit(task) ,并让它打开任务添加/编辑选项卡并加载该数据。 And in theory, the way to do that is to call the main, parent, controller, after setting the parent scope's variables, and fire off the doTabRouting() method.理论上,这样做的方法是在设置父作用域的变量后调用主、父、控制器,并触发doTabRouting()方法。 I'm able to set the variables the doTabRouting() uses, but I can't actually trigger the method.我可以设置doTabRouting()使用的变量,但我实际上无法触发该方法。

I've tried accessing it through $scope, but when I get into vm.openTaskAddEdit(), I get the awesome error of "$scope is not defined".我尝试通过 $scope 访问它,但是当我进入 vm.openTaskAddEdit() 时,我收到了“$scope 未定义”的可怕错误。

You will need to setup parent and child controller for them to access $scope object.您需要为他们设置父控制器和子控制器以访问 $scope 对象。

<div ng-controller="UserTasksCtrl">


    <!-- Tabs for Nav -->
    <ul class="nav nav-tabs">
        <li class="nav-item" id="headingTasks" ng-class="{ 'active': vm.tabTasks }">
            <a data-target="#tabTasks" data-toggle="tab" class="nav-link pt-1 pr-2 pb-1 pl-2"
               ng-class="{ 'active': vm.tabTasks }"
               ng-click="vm.loadTasks()">Tasks</a>
        </li>
        <li class="nav-item" id="headingAddEditTask" ng-class="{ 'active': vm.tabAddEditTasks }" ng-if="vm.tabAddEditTasks">
            <a data-target="#tabAddEditTasks" data-toggle="tab" class="nav-link pt-1 pr-2 pb-1 pl-2"
               ng-class="{ 'active': vm.tabAddEditTasks }">{{vm.addEditText}} <span ng-if="(vm.addEditUnsaved)" style="font-size: 85%;"><i class="fa fa-fw fa-warning text-warning"></i></span></a>
        </li>
    </ul>
    
    
    <div ng-controller="JobsCtrl">

        <!-- Tabs content -->
        <div class="tab-content">
            <!--Tasks-->
            <div id="tabTasks" class="tab-pane fade show tab-pane-bordered" ng-class="{ 'active show': vm.tabTasks}">
                <div class="row p-1 m-0">
                    <div class="col-12 p-0 m-0">
                        <div ng-include="vm.pageTasks"></div>
                    </div>
                </div>
            </div>

            <!--Add/Edit Task-->
            <div id="tabAddEditTasks" class="tab-pane fade show tab-pane-bordered" ng-class="{ 'active show': vm.tabAddEditTasks }">
                <div class="row p-1 m-0">
                    <div class="col-12 p-0 m-0">
                        <div ng-include="vm.pageAddEditTask"></div>
                    </div>
                </div>
            </div>
        </div>  
    
    </div>
</div>

It turns out that accessing a nested $parent within $parent was the key I needed.事实证明,访问 $parent 中嵌套的 $parent 是我需要的关键。 In the child controller, I passed in $scope into the init() as a parameter (eg init($scope), and then I set a vm.variable equal to that parameter (in this instance, 'scope') as such: vm.rootScope = scope.$parent.$parent.vm; . This gave me full access to everything declared in the parent controller, including functions, and allowed me to change the tabs.在子控制器中,我将 $scope 作为参数传入 init()(例如 init($scope),然后我将 vm.variable 设置为等于该参数(在本例中为“scope”),如下所示: vm.rootScope = scope.$parent.$parent.vm; . 这让我可以完全访问父控制器中声明的所有内容,包括函数,并允许我更改选项卡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM