从转换的HTML访问组件控制器(Accessing component controller from transcluded HTML)

系统教程 行业动态 更新时间:2024-06-14 16:57:40
从转换的HTML访问组件控制器(Accessing component controller from transcluded HTML)

Plunker ,因为片段编辑器今天不喜欢我。

快速信息

我正在使用.component()代替.directive()当使用Angular 1.6让我自己更多地使用Angular 2使用的设计模式类型时。问题是我不能使用任何引用$tabs或$tab (各个组件的控制器)。 使用{{$tab.tabsCtrl.nothing}}或{{$tabs.nothing}} {{$tab.tabsCtrl.nothing}}输出任何内容。

请注意:这不是我的实际情况,但它确实与我实际做的事情有共同的问题。

我已经四处寻找并获得了Angular 2组件的大量结果,但如果我老实说,那么它基本上都是希腊语。

代码参考(不在代码片段编辑器中工作,仅供参考)

// Code goes here
angular.module('main.app', [])
  .component('tabs', {
    controller: function($http) {
      this.tabs = [];
      this.nothing = 'nada';
      this.addTab = function(tab) {
        this.tabs.push(tab);
      }; //end addTab
      this.selectTab = function(tab) {
        this.tabs.map(function(item) {
          item.selected = false;
        });
        var selected = this.tabs.filter(function(item) {

          return item === tab;
        });
        if (selected.length) selected[0].selected = true;
      }; //End selectTab
    },
    template: '<ul class="nav nav-tabs nav-justify justify-content-center"><li class="nav-item" ng-repeat="tab in $tabs.tabs" ><a href="#" ng-click="$tabs.selectTab(tab)" class="nav-link" ng-class="{\'active\':tab.selected}">{{tab.tabTitle}}</a></li></ul><div class="tabs-content" ng-transclude></div>',
    transclude: true,
    controllerAs: '$tabs'
  })
  .component('tab', {
    require: {
      'tabsCtrl': '^tabs'
    },
    bindings: {
      'tabTitle': '@',
      'selected': '<'
    },
    controller: function() {
      this.$onInit = function() {
        this.selected = this.selected || false;
        this.tabsCtrl.addTab(this);
      }; //end $onInit
    },
    transclude: true,
    controllerAs: '$tab',
    template: '<div class="tab" ng-show="$tab.selected"><div ng-transclude></div></div>'
  })

Code Reference(not working in snippet editor, only for reference)

// Code goes here
angular.module('main.app', [])
  .component('tabs', {
    controller: function($http) {
      this.tabs = [];
      this.nothing = 'nada';
      this.addTab = function(tab) {
        this.tabs.push(tab);
      }; //end addTab
      this.selectTab = function(tab) {
        this.tabs.map(function(item) {
          item.selected = false;
        });
        var selected = this.tabs.filter(function(item) {

          return item === tab;
        });
        if (selected.length) selected[0].selected = true;
      }; //End selectTab
    },
    template: '<ul class="nav nav-tabs nav-justify justify-content-center"><li class="nav-item" ng-repeat="tab in $tabs.tabs" ><a href="#" ng-click="$tabs.selectTab(tab)" class="nav-link" ng-class="{\'active\':tab.selected}">{{tab.tabTitle}}</a></li></ul><div class="tabs-content" ng-transclude></div>',
    transclude: true,
    controllerAs: '$tabs'
  })
  .component('tab', {
    require: {
      'tabsCtrl': '^tabs'
    },
    bindings: {
      'tabTitle': '@',
      'selected': '<'
    },
    controller: function() {
      this.$onInit = function() {
        this.selected = this.selected || false;
        this.tabsCtrl.addTab(this);
      }; //end $onInit
    },
    transclude: true,
    controllerAs: '$tab',
    template: '<div class="tab" ng-show="$tab.selected"><div ng-transclude></div></div>'
  }) 
  
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
<tabs>
  <tab tab-title="First Tab" selected="true">
    <div class="jumbotron">
      <h3>Lorem ipsum.</h3>
      <p class="lead">Lorem ipsum dolor sit amet.</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto, in!</p>
    </div>
    some other text
  </tab>
  <tab tab-title="Second Tab">
    <strong>With a header!</strong>
    <div class="row">
      <div class="col-6 bg-primary">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi, quam, quod, optio qui cum rerum vel eos rem aspernatur quia maxime incidunt numquam ipsum eum neque dicta distinctio. Minus, itaque.</div>
      <div class="col-6 bg-danger">Reprehenderit, numquam, rerum, reiciendis neque adipisci provident ea quo illo praesentium inventore fuga quisquam ducimus? Ipsum, autem, illo ullam corporis incidunt ad labore accusantium tempora officia quas quia eaque facere.</div>
    </div>
  </tab>
  <tab tab-title="Potato Tab">
    <h3>Big books {{$tabs.nothing||'nah'}}</h3>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iste quos assumenda vero fugiat officia pariatur consequatur deserunt quisquam veniam nemo?</p>
    <p>Fugiat, error, impedit, accusantium consequuntur beatae facere esse voluptatum enim animi porro commodi modi cupiditate aliquam iure ipsa. A, officiis!</p>
    <p>Architecto velit quod explicabo laborum reprehenderit culpa tempora facilis minima eum. Natus aliquid eaque laboriosam accusamus dolor hic similique ad.</p>
  </tab>
</tabs> 
  
 

Thanks, just in case I forget to say it in the future!

最满意答案

转换范围将是指令的隔离范围的子范围。

由于组件使用隔离范围,因此只需执行{{$tabs.nothing}}就无法使用原型继承。 如果通过$rootScope公开$tabs ,或者层次结构中的选项卡上方的任何其他非隔离范围(在您的示例中仅为ng-app ,因此只有$rootScope ),它将起作用。

您可以手动遍历范围链。

根据您的示例:

当前范围将是tab指令的transcluded子范围 第一个$parent将是isolate tab范围 第二个$parent将是tabs指令的transcluded子范围 第三个$parent将是isolate tab范围

这给出了:

{{$parent.$parent.$parent.$tabs.nothing}}

演示: http //plnkr.co/edit/jpTGVKWKEQlmGYpaeqtZ?p = preview

在大多数情况下,这不是一个可行的解决方案。 可能更好地通过服务公开转换内容所需的功能。

在不知道真实用例的情况下很难提供更好的解决方案。

The transcluded scope will be a child scope of the directive's isolate scope.

Since components use isolate scopes, you can't make use of prototypal inheritance by just doing {{$tabs.nothing}}. It would work if $tabs was exposed via $rootScope however, or any other non-isolate scope above tabs in the hierarchy (only ng-app in your example, so only $rootScope).

You can walk the scope chain manually.

Based on your example:

The current scope would be the transcluded child scope of the tab directive The first $parent would be the isolate tab scope The second $parent would be the transcluded child scope of the tabs directive The third $parent would be the isolate tab scope

This gives:

{{$parent.$parent.$parent.$tabs.nothing}}

Demo: http://plnkr.co/edit/jpTGVKWKEQlmGYpaeqtZ?p=preview

In most cases this isn't really a feasible solution. Probably better to expose the functionality that the transcluded content needs via a service.

Hard to give a better solution without knowing the real use case.

更多推荐

本文发布于:2023-04-13 12:16:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/dzcp/3468956966d7ee3cd019ceeb98568de9.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:控制器   组件   HTML   Accessing   transcluded

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!