你能在 Angular 中嵌入一个子指令吗?
Can you transclude into a child directive in Angular?
我希望能够在我的应用程序中执行类似的操作:
<pill-autocomplete>
<pill-template>{{item.name}}</pill-template>
</pill-autocomplete>
其中 pill-autocomplete
有一个模板可以像这样嵌入到子指令中:
<pills ng-transclude="pillTemplate"></pills>
<input type="text">
鉴于 ng-transclude 创建作用域并且 <pills>
指令具有隔离作用域,这似乎是不可能的。
我想到的一种实现方法是在自动完成的模板函数中注入 pill 模板。问题在于它失去了包含范围。我还必须在每个与药丸具有相似行为的指令中执行此操作。
在 angular 1.x 中还有其他方法可以实现吗?
这是一种可能将数据输入 child DDO 的方法。如果有任何不清楚的地方,请告诉我,希望对您有所帮助。
function exampleController($scope) {
$scope.data = [
'cupidatat',
'laboris',
'minim',
'nisi',
'anim',
'id',
'laboris'
];
}
function exampleParentDirective() {
return {
restrict: 'E',
scope: {
data: '='
},
template: '<div class="parent-example"></div>'
//optionally you could potentially use the child
//directive in the template of this DDO.
//template: '<div class="parent-example"><example-directive data="data"></example-directive></div>'
};
}
function exampleDirective() {
return {
restrict: 'E',
scope: {
data: '='
},
template: '<div class="child-example" ng-repeat="ipsum in data track by $index" ng-bind="ipsum"></div>',
link: function($scope) {
//link function not need unless you need other processing done in child directive.
}
};
}
angular
.module('app', [])
.controller('exampleController', exampleController)
.directive('exampleParentDirective', exampleParentDirective)
.directive('exampleDirective', exampleDirective);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="container" ng-app="app">
<div class="row" ng-controller="exampleController">
<example-parent-directive data="data"></example-parent-directive>
<example-directive data="data"></example-directive>
</div>
</div>
这个演示可能有帮助
https://docs.angularjs.org/guide/directive
index.html
<my-tabs>
<my-pane title="Hello">
<p>Lorem ipsum dolor sit amet</p>
</my-pane>
<my-pane title="World">
<em>Mauris elementum elementum enim at suscipit.</em>
<p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
</my-pane>
</my-tabs>
我的-tabs.html
<div class="tabbable">
<ul class="nav nav-tabs">
<li ng-repeat="pane in panes" ng-class="{active:pane.selected}">
<a href="" ng-click="select(pane)">{{pane.title}}</a>
</li>
</ul>
<div class="tab-content" ng-transclude></div>
</div>
我的-pane.html
<div class="tab-pane" ng-show="selected">
<h4>{{title}}</h4>
<div ng-transclude></div>
</div>
当然 script.js
angular.module('docsTabsExample', [])
.directive('myTabs', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: ['$scope', function MyTabsController($scope) {
var panes = $scope.panes = [];
$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
};
this.addPane = function(pane) {
if (panes.length === 0) {
$scope.select(pane);
}
panes.push(pane);
};
}],
templateUrl: 'my-tabs.html'
};
})
.directive('myPane', function() {
return {
require: '^^myTabs',
restrict: 'E',
transclude: true,
scope: {
title: '@'
},
link: function(scope, element, attrs, tabsCtrl) {
tabsCtrl.addPane(scope);
},
templateUrl: 'my-pane.html'
};
});
问题是,当您将数据从 pill-autocomplete 转入 pills 时,您已经删除了 pills 中的内容。
嵌入替换了指令模板下的内容,因此 pills 指令模板中的内容根本无法加载,因为已被嵌入覆盖。
我的建议很简单,不要直接使用里面有 ng-transclude 的标签,使用一个内部的 div 来让指令加载它的内容成为可能
angular.module('app', []);
var app = angular.module('app');
'use strict';
var app = angular.module('app');
app.controller('testController', [
function () {
var vm = this;
vm.name = 'Jimmy';
}]);
app.directive('pillAutocomplete', function () {
return {
priority: 100,
restrict: 'E',
transclude: true,
template: '<pills><p>From Pill-Autocomplete</p><div ng-transclude><div></pills>'
};
});
app.directive('pills', function () {
return {
restrict: 'E',
transclude: true,
link: function (scope, element, attrs) {
scope.style = true;
},
template: '<p>Inside Pills</p><div ng-class="{pillscolor : style}" ng-transclude></div>'
};
});
.pillscolor{
color: green;
font-size: 20px;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<article ng-app="app">
<section ng-controller="testController as test">
Controller scope - {{test.name}}
<pill-autocomplete>
From controller - {{test.name}}
</pill-autocomplete>
</section>
</article>
我希望能够在我的应用程序中执行类似的操作:
<pill-autocomplete>
<pill-template>{{item.name}}</pill-template>
</pill-autocomplete>
其中 pill-autocomplete
有一个模板可以像这样嵌入到子指令中:
<pills ng-transclude="pillTemplate"></pills>
<input type="text">
鉴于 ng-transclude 创建作用域并且 <pills>
指令具有隔离作用域,这似乎是不可能的。
我想到的一种实现方法是在自动完成的模板函数中注入 pill 模板。问题在于它失去了包含范围。我还必须在每个与药丸具有相似行为的指令中执行此操作。
在 angular 1.x 中还有其他方法可以实现吗?
这是一种可能将数据输入 child DDO 的方法。如果有任何不清楚的地方,请告诉我,希望对您有所帮助。
function exampleController($scope) {
$scope.data = [
'cupidatat',
'laboris',
'minim',
'nisi',
'anim',
'id',
'laboris'
];
}
function exampleParentDirective() {
return {
restrict: 'E',
scope: {
data: '='
},
template: '<div class="parent-example"></div>'
//optionally you could potentially use the child
//directive in the template of this DDO.
//template: '<div class="parent-example"><example-directive data="data"></example-directive></div>'
};
}
function exampleDirective() {
return {
restrict: 'E',
scope: {
data: '='
},
template: '<div class="child-example" ng-repeat="ipsum in data track by $index" ng-bind="ipsum"></div>',
link: function($scope) {
//link function not need unless you need other processing done in child directive.
}
};
}
angular
.module('app', [])
.controller('exampleController', exampleController)
.directive('exampleParentDirective', exampleParentDirective)
.directive('exampleDirective', exampleDirective);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="container" ng-app="app">
<div class="row" ng-controller="exampleController">
<example-parent-directive data="data"></example-parent-directive>
<example-directive data="data"></example-directive>
</div>
</div>
这个演示可能有帮助
https://docs.angularjs.org/guide/directive
index.html
<my-tabs>
<my-pane title="Hello">
<p>Lorem ipsum dolor sit amet</p>
</my-pane>
<my-pane title="World">
<em>Mauris elementum elementum enim at suscipit.</em>
<p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
</my-pane>
</my-tabs>
我的-tabs.html
<div class="tabbable">
<ul class="nav nav-tabs">
<li ng-repeat="pane in panes" ng-class="{active:pane.selected}">
<a href="" ng-click="select(pane)">{{pane.title}}</a>
</li>
</ul>
<div class="tab-content" ng-transclude></div>
</div>
我的-pane.html
<div class="tab-pane" ng-show="selected">
<h4>{{title}}</h4>
<div ng-transclude></div>
</div>
当然 script.js
angular.module('docsTabsExample', [])
.directive('myTabs', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: ['$scope', function MyTabsController($scope) {
var panes = $scope.panes = [];
$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
};
this.addPane = function(pane) {
if (panes.length === 0) {
$scope.select(pane);
}
panes.push(pane);
};
}],
templateUrl: 'my-tabs.html'
};
})
.directive('myPane', function() {
return {
require: '^^myTabs',
restrict: 'E',
transclude: true,
scope: {
title: '@'
},
link: function(scope, element, attrs, tabsCtrl) {
tabsCtrl.addPane(scope);
},
templateUrl: 'my-pane.html'
};
});
问题是,当您将数据从 pill-autocomplete 转入 pills 时,您已经删除了 pills 中的内容。
嵌入替换了指令模板下的内容,因此 pills 指令模板中的内容根本无法加载,因为已被嵌入覆盖。
我的建议很简单,不要直接使用里面有 ng-transclude 的标签,使用一个内部的 div 来让指令加载它的内容成为可能
angular.module('app', []);
var app = angular.module('app');
'use strict';
var app = angular.module('app');
app.controller('testController', [
function () {
var vm = this;
vm.name = 'Jimmy';
}]);
app.directive('pillAutocomplete', function () {
return {
priority: 100,
restrict: 'E',
transclude: true,
template: '<pills><p>From Pill-Autocomplete</p><div ng-transclude><div></pills>'
};
});
app.directive('pills', function () {
return {
restrict: 'E',
transclude: true,
link: function (scope, element, attrs) {
scope.style = true;
},
template: '<p>Inside Pills</p><div ng-class="{pillscolor : style}" ng-transclude></div>'
};
});
.pillscolor{
color: green;
font-size: 20px;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<article ng-app="app">
<section ng-controller="testController as test">
Controller scope - {{test.name}}
<pill-autocomplete>
From controller - {{test.name}}
</pill-autocomplete>
</section>
</article>