这是问题所在。我有一些名为 main-directive 的第三方指令。
app.directive('mainDirective', function() {
return {
scope: {
foo: '&'
// attrs
},
controller: function($scope) {
$scope.click = function() {
window.alert($scope.foo());
}
},
template: '<button ng-click="click()">Click me</button>'
}
});
所以我想创建一个名为 parent-directive 的指令,它将特定于应用程序的默认值分配给第三方指令属性。
app.directive('parentDirective', function() {
return {
scope: {
foo: '&?',
attr2: '='
// lots of attrs
},
controller: function($scope) {
$scope.attr1 = "some default value"
$scope.foo = function() {
return "not overrided"
}
if (this.foo) {
$scope.foo = this.foo
}
},
template: '<div class="some-styling"><main-directive foo="foo()" attr1="attr1" attr2="attr2"></main-directive></div>'
}
});
如果我想制作另一个子指令来保持父指令逻辑,该怎么办? 重载属性很容易我可以使用&#34;编译&#34;功能。但是覆盖功能怎么样呢?
app.directive('childDirective', function() {
return {
scope: false,
require: 'parentDirective',
link: function(scope, element, attr, controller) {
controller.foo = function() {
return "overrided";
}
},
compile: function(element, attr) {
attr.attr2 = "attr2";
}
}
});
通过使用子范围而不是隔离,可以轻松完成所有事情。 或者通过使用模板扩展。但如果我用模板扩展指令,我将不得不复制父&#34;范围&#34;和&#34;模板&#34;定义到child-directive并转发所有非默认属性,这似乎不是一个优雅的解决方案。
所以关键问题是,有没有办法使用隔离范围覆盖父指令函数而不转发属性。
以下是DEMO
答案 0 :(得分:0)
好的,我做了一些研究,结果发现可以有几种方法
范围继承
由于child-directive未创建自己的范围,因此只需在parent-directive父范围创建新方法。因此我们可以在编译期间修改属性并指定重写的foo方法。
app.directive('parentDirective', function() {
return {
scope: {
fooImpl: '&?',
// lots of attrs
},
controller: function($scope) {
$scope.foo = function() {
if ($scope.fooImpl) {
return $scope.fooImpl();
}
return "not overrided";
}
},
template: '<div class="some-styling"><main-directive foo="foo()"></main-directive></div>'
}
});
app.directive('childDirective', function() {
return {
scope: false,
require: 'parentDirective',
controller: function($scope) {
$scope.foo = function() {
return "overrided";
}
},
compile: function(element, attr) {
attr.fooImpl = "foo()";
}
}
});
以下是DEMO1
添加到隔离范围
Angular提供特殊功能。这可以从元素中获得孤立的范围。所以我们可以在链接阶段覆盖我们的方法。
app.directive('parentDirective', function() {
return {
scope: {
fooImpl: '&?',
// lots of attrs
},
controller: function($scope) {
$scope.foo = function() {
if ($scope.fooImpl) {
return $scope.fooImpl();
}
return "not overrided";
}
},
template: '<div class="some-styling"><main-directive foo="foo()"></main-directive></div>'
}
});
app.directive('childDirective', function() {
return {
scope: false,
require: 'parentDirective',
link: function(scope, element, attr) {
var innerScope = angular.element(element[0]).isolateScope();
innerScope.foo = function() {
return "overrided";
}
}
}
});
以下是DEMO2
控制器方法
如果我们使用controllerAs语法。这意味着我们将控制器对象变量公开为范围。我们可以在链接阶段覆盖子指令中的函数。
app.directive('parentDirective', function() {
return {
scope: {
fooImpl: '&?',
// lots of attrs
},
controller: function($scope) {
var vm = this;
vm.foo = function() {
return "not overrided";
}
},
controllerAs : 'vm',
template: '<div class="some-styling"><main-directive foo="vm.foo()"></main-directive></div>'
}
});
app.directive('childDirective', function() {
return {
scope: false,
require: 'parentDirective',
link: function (scope, element, attr, controller) {
controller.foo = function() {
return "overrided";
}
}
}
});
以下是DEMO3
<强> Transclusion 强>
实际上,您可以使用单独的父级和子级指令以及使用翻译来执行相同的操作。但无论如何,它将是上述方法的组合。感谢"Extending an existing directive in AngularJS"