【问题标题】:Expose element of parent component to child将父组件的元素暴露给子组件
【发布时间】:2017-03-29 17:56:13
【问题描述】:

我有一个主要组件来处理我的 Angular 应用程序的工具栏和 sidnav。我想让工具栏中的 div 可供子组件(和控制器)自定义,以便他们可以执行更改工具栏标题文本和添加上下文按钮等操作。这感觉有点像转置的反面,父组件可以自定义子组件的一部分(例如,菜单组件自定义按钮的内容)。一种选择是让工具栏由服务管理,但即便如此,我也想不出一种很好的方法来自定义工具栏的内容,而无需执行大量构建 dom 元素的 javascript(我做的事情之一)总是尽量避免角度)。

【问题讨论】:

    标签: angularjs angularjs-components


    【解决方案1】:

    在 Angular 1.6.x components 中仅使用隔离范围:

    组件只控制自己的视图和数据:组件应该 永远不要修改任何超出其自身范围的数据或 DOM。一般, 在 AngularJS 中,可以在应用程序的任何地方修改数据 通过范围继承和监视。这个很实用,但也可以 当不清楚应用程序的哪个部分是时会导致问题 负责修改数据。这就是为什么组件指令 使用隔离范围,所以整个范围的操作不是 可能。

    因此,要完成这项工作,您需要使用指令而不是组件。您要包含的 div 本身需要是一个指令,才能更改工具栏指令的父范围。您要做的是将一个指令嵌入到另一个指令中,并使用共享作用域来更改父作用域。

    这篇文章对于您要完成的工作来说是一个非常好的资源。我将从这里开始:https://www.airpair.com/angularjs/posts/transclusion-template-scope-in-angular-directives

    我已经更改了该文章中的示例 Codepen,以向您展示它的工作原理:http://codepen.io/jdoyle/pen/aJQpYo

    如果您选择列表中的项目,您可以看到标题名称更改为所选内容。

    angular.module("ot-components", [])
    
    .controller("AppController",($scope)=> {
      //Normally, this data would be wrapped in a service. For example only.
      $scope.header = "Marketing";
      $scope.areas = {
        list: [
          "Floorplan",
          "Combinations",
          "Schedule",
          "Publish"
        ],
        current: "Floorplan"
      };
    })
    
    .directive("otList", ()=> {
      return {
        scope: false,  // this is one of the major changes
        template: 
        `<ul class="ot-list">
          <li class="ot-list--item"
            ng-repeat="item in items"
            ng-bind="item"
            ng-class="{'ot-selected': item === selected}"
            ng-click="selectItem(item)">
           </li>
        </ul>`,
        link: (scope, elem, attrs) => {
          scope.items = JSON.parse(attrs.items);
          scope.selected = attrs.selected;
    
          scope.selectItem = (item) => {
            scope.selected = item;
            scope.$parent.header = item;  // this is the other major change
          };
        }
      };
    })
    
    .directive("otSite", ()=> {
      return {
        scope: true,  // another major change
        transclude: true,
        template: 
        `<div class="ot-site">
            <div class="ot-site--head">
              <img class="ot-site--logo" src="//guestcenter.opentable.com/Content/img/icons/icon/2x/ot-logo-2x.png">
            <h1>{{header}}</h1>
            </div>
            <div class="ot-site--menu">
            </div>
            <div class="ot-site--body" ng-transclude>
            </div>
            <div class="ot-site--foot">
              &copy; 2015 OpenTable, Inc.
            </div>
          </div>`     
      };
    });
    

    【讨论】:

      猜你喜欢
      • 2019-09-02
      • 1970-01-01
      • 1970-01-01
      • 2012-12-21
      • 2018-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      相关资源
      最近更新 更多