【问题标题】:Access the most parent controller from child component从子组件访问最父控制器
【发布时间】:2018-01-16 13:54:47
【问题描述】:

我在我的应用程序中使用 angular 1.5 组件,这是我的结构:

<body ng-app ng-controller="appController as app">
    <div ui-view="home">
        <home-component>
            {{ app.user }}
        </home-component>
    </div>
</body> 

基本上,我将 ui-router 与 Angular 组件一起用于嵌套视图。

我知道,使用controller as 语法,您可以访问父控制器,但由于某种原因我不能。 {{ app.user }} 没有显示任何内容

现在我已经阅读了,组件的范围是隔离的,但我认为这只是意味着父组件无法访问子组件。

如果它是完全隔离的,我将如何访问父控制器中的全局数据?

谢谢!

【问题讨论】:

    标签: angularjs angularjs-scope angular-components angular1.6


    【解决方案1】:

    如果一个指令是孤立的,最好通过参数传递您需要使用的任何值,否则为什么要使其孤立?

    <home-component user="app.user"></home-component>
    
    .directive('homeComponent', function() {
      return {
        scope: { user: '=' },
        ...
      }
    })
    

    或者,如果子指令中不需要使用内容,您可以将其嵌入

    <home-component>
        {{ app.user }}
    </home-component>
    
    .directive('homeComponent', function() {
      return {
        transclude: true,
        template: '<div><ng-transclude></ng-transclude></div>',
        ...
      }
    })
    

    【讨论】:

    • 组件是一种与指令略有不同的动物,并且具有旨在处理 OP 询问的特定功能。因为在大多数情况下,Angular 1.5 组件比用于创建 DOM 的指令更可取。
    • @MikeFeltman 感谢您介绍组件,但不知道它们存在。当我阅读文档时,我觉得我的观点仍然成立。为什么通过绑定上层让组件需要特定的父级,而不是使用 attr 传递所需的数据以便组件可以被重用?
    【解决方案2】:

    使用require property 访问父控制器和映射 绑定到子组件的控制器:

    app.component("homeComponent", {
      require: {main: "^ngController"},
      template: 
        `<fieldset>
          <h3>home-component</h3>
          <p> $ctrl.main.user = {{$ctrl.main.user}}</p>
        </fieldSet>`
    })
    

    上面的例子绑定到ng-controller directive的控制器。

    来自文档:

    组件间通信

    指令可以require其他指令的控制器来实现彼此之间的通信。这可以通过为require 属性提供对象映射在组件中实现。对象键指定所需控制器(对象值)将在其下绑定到所需组件的控制器的属性名称。

    — AngularJS Developer Guide - Components (Intercomponent Communication)

    The DEMO

    angular.module("app",[])
    .component("homeComponent", {
      require: {main: "^ngController"},
      template: 
        `<fieldset>
          <h3>home-component</h3>
          <p> $ctrl.main.user = {{$ctrl.main.user}}</p>
        </fieldSet>`
    })
    .controller("appController", function() {
      var main = this;
      main.user = "someUser";
    })
    <script src="//unpkg.com/angular/angular.js"></script>
      <body ng-app="app" ng-controller="appController as main">
          <h2>Main App</h2>
          <input ng-model="main.user" />
          <br><br>
          <home-component>
          </home-component>
      </body> 

    【讨论】:

    • 我最终使用了您的答案,因为我有 ng-controller 可供参考!效果很好,谢谢!但我想@Mike FeltMan 的答案也有效。唯一的区别是一个引用控制器,另一个引用组件。
    【解决方案3】:

    您可以使用 requires 在子组件中创建对它的引用。

    这个语法基本上到处都能找到它:

    require: {
          app: '^homeComponent'
        }
    

    或者这种语法只会为组件查找一个作为父组件:

    require: {
          app: '^^homeComponent'
        }
    

    然后在子组件中,您可以通过 app 属性引用 homeComponent。

    您还可以通过在它前面加上一个 ? 来使引用成为可选的。喜欢:

      app: '?^^homeComponent'
    

    【讨论】:

    • 非常感谢!我最终选择了@georgeawg 所拥有的,主要是因为他引用了控制器本身而不是组件。但是想象一下,这对于引用父组件非常有用。出于某种原因,我一直认为它会向上查找一级,但显然它会查找高于它的所有级别。
    猜你喜欢
    • 2018-04-02
    • 2020-04-16
    • 2018-11-15
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多