从嵌入的 HTML 访问组件控制器
Accessing component controller from transcluded HTML
Plunker,因为代码片段编辑器今天不喜欢我。
快速信息
我正在努力在使用 Angular 1.6 时使用 .component()
代替 .directive()
以使自己更多地了解 Angular 2 使用的设计模式类型. 问题是我不能使用任何对 $tabs
或 $tab
的引用(这些组件的控制器)。使用 {{$tab.tabsCtrl.nothing}}
或 {{$tabs.nothing}}
.
不会输出任何内容
请Note:this不是我的实际情况,但它确实与我实际做的事情有共同的问题。
我四处搜索,得到了很多关于 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>'
})
<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>
谢谢,以防以后忘记说!
嵌入的作用域将是指令隔离作用域的子作用域。
由于组件使用隔离作用域,因此您不能仅通过 {{$tabs.nothing}}
来利用原型继承。但是,如果 $tabs
通过 $rootScope
公开,或者层次结构中选项卡上方的任何其他 non-isolate 范围(在您的示例中仅 ng-app
,因此仅 $rootScope
).
您可以手动遍历作用域链。
根据你的例子:
- 当前范围将是
tab
指令的嵌入子范围
- 第一个
$parent
将是隔离 tab
作用域
- 第二个
$parent
将是 tabs
指令的嵌入子作用域
- 第三个
$parent
将是隔离 tab
作用域
这给出:
{{$parent.$parent.$parent.$tabs.nothing}}
演示: http://plnkr.co/edit/jpTGVKWKEQlmGYpaeqtZ?p=preview
在大多数情况下,这并不是真正可行的解决方案。通过服务公开嵌入内容所需的功能可能更好。
在不了解实际用例的情况下很难给出更好的解决方案。
Plunker,因为代码片段编辑器今天不喜欢我。
快速信息
我正在努力在使用 Angular 1.6 时使用 .component()
代替 .directive()
以使自己更多地了解 Angular 2 使用的设计模式类型. 问题是我不能使用任何对 $tabs
或 $tab
的引用(这些组件的控制器)。使用 {{$tab.tabsCtrl.nothing}}
或 {{$tabs.nothing}}
.
请Note:this不是我的实际情况,但它确实与我实际做的事情有共同的问题。
我四处搜索,得到了很多关于 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>'
})
<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>
谢谢,以防以后忘记说!
嵌入的作用域将是指令隔离作用域的子作用域。
由于组件使用隔离作用域,因此您不能仅通过 {{$tabs.nothing}}
来利用原型继承。但是,如果 $tabs
通过 $rootScope
公开,或者层次结构中选项卡上方的任何其他 non-isolate 范围(在您的示例中仅 ng-app
,因此仅 $rootScope
).
您可以手动遍历作用域链。
根据你的例子:
- 当前范围将是
tab
指令的嵌入子范围 - 第一个
$parent
将是隔离tab
作用域 - 第二个
$parent
将是tabs
指令的嵌入子作用域 - 第三个
$parent
将是隔离tab
作用域
这给出:
{{$parent.$parent.$parent.$tabs.nothing}}
演示: http://plnkr.co/edit/jpTGVKWKEQlmGYpaeqtZ?p=preview
在大多数情况下,这并不是真正可行的解决方案。通过服务公开嵌入内容所需的功能可能更好。
在不了解实际用例的情况下很难给出更好的解决方案。