【问题标题】:Access parent controller n levels higher访问更高级别的父控制器
【发布时间】:2016-08-23 13:16:36
【问题描述】:

我有一个页面控制器,在这里简化

angular.module('app').controller('MyCtrl', function () {
    this.name = 'David'
});

我在我的模板中使用了 controllerAs 语法(MyCtrl 作为 main),所以我只在我的模板中使用 ma​​in.name 来访问名称。都很好。

在我的模板中,我有一堆嵌套指令,它们创建了新的作用域,在底部的某处我有一个 ng=controller="SubCtrl as subController"。我现在可以通过 subcontroller.property 访问子控制器上的属性,并且在该模板中我仍然可以访问 ma​​in.name 因为 controllerAs 很棒。

问题在于,在我的第二个控制器代码中,我需要访问父控制器中的内容,此时父控制器的深度为 n 级。我知道我可以在主控制器中这样做......

$scope.main = this;

然后在第二个控制器中执行此操作

var main = $scope.$parent.$parent.$parent.$parent.main;

但我们都知道我们不应该这样做,而且我也不知道它有多深,因为我不知道开发人员在其中放置了多少指令来创建新范围。

我听到一些人在谈论为此创建一个服务,但这听起来很难通用,我不希望我的框架的用户每次将包含放入标签面板,那太疯狂了。

所以,我目前的想法是使用作用域并编写一个函数,该函数将遍历父作用域,直到找到您使用比较函数指定的作用域。不过我觉得可能有更好的方法。

【问题讨论】:

  • 谁会在不暴露问题的情况下投票否决问题?我认为我解释得很好,这是一个完全有效的问题。
  • 那么为什么不创建一个服务呢?服务是存储数据或访问多个控制器、指令、工厂等所需内容的好地方。它基本上是一个单例,你在多个地方注入,但它总是被注入同一个实例。它非常易于使用,并且比您想象的要脆弱得多($parent.$parent.n.....data)。如果您进行单元测试,它也更易于测试。
  • 我去过那里,我向您保证,如果您想在控制器之间共享信息,没有什么比服务更好的了。例如:用于存储用户infoService 信息的服务。 mainCtrl 可以做infoService.registerUser({name : 'David'}) 然后subCtrl 可以做infoService.getLatestUser()
  • 我不确定我是否理解。我不仅有一个需要从嵌套子控制器访问的控制器,我在所有应用程序中都有它们,它们可以访问不同的父级。我实际上需要访问控制器的方法和数据(控制器中附加到“this”的所有内容),所以我是否需要为我想要执行此操作的每个场景创建一个新服务?我认为它是单例的事实是问题所在?
  • 你说得好像它只是一段数据。是的,您仍然应该将共享的业务逻辑抽象到工厂(如果没有状态共享)或服务(如果有状态共享)中,然后在必要时/在必要时将它们注入您的控制器。尽可能保持一切模块化。

标签: javascript angularjs scope angular-controller


【解决方案1】:

那么为什么不创建一个服务呢?服务是存储数据或访问多个控制器、指令、工厂等所需内容的好地方。它基本上是一个单例,你在多个地方注入,但它总是被注入同一个实例,并且只在第一次需要它时创建。它非常易于使用,并且比您想象的 ($parent.$parent.n.....data) 要少得多。如果您进行单元测试,它也更易于测试。

var module = angular.module('app');

module.service('commonService', function () {
    this.sharedData = {name: ''};
});

// assume this gets loaded first
module.controller('MyCtrl1', ['commonService', function (commonService) {
    commonService.sharedData.name = 'David'
}]);

// and this is loaded somewhere after MyCtrl2
module.controller('MyCtrl2', ['commonService', function (commonService) {
    var name = commonService.sharedData.name;
}]);

我还没有验证语法,但这是基本结构,非常简单。

【讨论】:

  • 好的,所以每次我有一个祖父母 > 子场景(字面意思是我的应用程序中具有标签系统的页面)时,我是否需要这样做,或者我是否能够存储他们都在服务上,例如服务可以有一个键值对映射,其中每个键是一个唯一的控制器名称,每个值是对控制器实例的引用?
  • @jonhobbs - 服务只不过是一个只创建一次的对象,因此它可以包含您想要的任何内容,包括对控制器的引用。作为 OOP 规则,尽管类型彼此了解的越少,程序就越灵活,因此始终建议使用 loose coupling。我会将公共/共享状态和公共/共享业务逻辑抽象为一个或多个服务(或工厂,如果没有共享状态),这是控制器之间“通信”的最佳方式。
猜你喜欢
  • 2016-01-25
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
相关资源
最近更新 更多