如何:AngularJS - 从子控制器访问父控制器中的方法
How To: AngularJS - Access method in parent controller from child controller
我有一个 AngularJs 页面,在 UI 中有标签。每个选项卡加载不同的数据。其中之一是用户的任务列表。用户可以在此选项卡上搜索各种任务,当他们找到一个任务时,可以单击它,它将在另一个选项卡上弹出该任务的编辑表单。
我不知道如何显示其他选项卡,因为选项卡选择驻留在父控制器(主页)中,并且选项卡都有自己的子控制器。
父控制器:
"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;
}
}
);
}
]);
子控制器:
"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";
}
);
}
]);
带有选项卡的 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>
我希望能够从任务列表选项卡调用 vm.openTaskAddEdit(task)
,让它打开任务 add/edit 选项卡并加载该数据。从理论上讲,这样做的方法是在设置父作用域的变量后调用 main、parent、controller,然后触发 doTabRouting()
方法。我可以设置 doTabRouting()
使用的变量,但实际上我无法触发该方法。
我试过通过 $scope 访问它,但是当我进入 vm.openTaskAddEdit() 时,我得到了“$scope 未定义”的可怕错误。
您需要设置父子控制器,以便它们访问 $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>
事实证明,访问 $parent 中的嵌套 $parent 是我需要的关键。在子控制器中,我将 $scope 作为参数传递给 init()(例如 init($scope)),然后我将 vm.variable 设置为等于该参数(在本例中,'scope' ) 这样:vm.rootScope = scope.$parent.$parent.vm;
。这让我可以完全访问父控制器中声明的所有内容,包括函数,并允许我更改选项卡。
我有一个 AngularJs 页面,在 UI 中有标签。每个选项卡加载不同的数据。其中之一是用户的任务列表。用户可以在此选项卡上搜索各种任务,当他们找到一个任务时,可以单击它,它将在另一个选项卡上弹出该任务的编辑表单。
我不知道如何显示其他选项卡,因为选项卡选择驻留在父控制器(主页)中,并且选项卡都有自己的子控制器。
父控制器:
"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;
}
}
);
}
]);
子控制器:
"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";
}
);
}
]);
带有选项卡的 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>
我希望能够从任务列表选项卡调用 vm.openTaskAddEdit(task)
,让它打开任务 add/edit 选项卡并加载该数据。从理论上讲,这样做的方法是在设置父作用域的变量后调用 main、parent、controller,然后触发 doTabRouting()
方法。我可以设置 doTabRouting()
使用的变量,但实际上我无法触发该方法。
我试过通过 $scope 访问它,但是当我进入 vm.openTaskAddEdit() 时,我得到了“$scope 未定义”的可怕错误。
您需要设置父子控制器,以便它们访问 $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>
事实证明,访问 $parent 中的嵌套 $parent 是我需要的关键。在子控制器中,我将 $scope 作为参数传递给 init()(例如 init($scope)),然后我将 vm.variable 设置为等于该参数(在本例中,'scope' ) 这样:vm.rootScope = scope.$parent.$parent.vm;
。这让我可以完全访问父控制器中声明的所有内容,包括函数,并允许我更改选项卡。