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 scopeThis 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.
更多推荐
发布评论