我正在构建一个可以在不同控制器中使用的指令,我希望能够将指令绑定到我的$scope
的特定属性。
我想做这样的事情:
<div ng-app="myapp">
<div ng-controller="myController">
<my-directive-wrapper ng-model="mymodel">
<my-directive-inner ng-repeat="item in items" />
</my-directive-wrapper>
</div>
</div>
使用这个模型:
$scope.mymodel = {
name : "Transclude test",
items : [
{ title : "test1" },
{ title : "test2" },
{ title : "test3" }
]
};
因此指令myDirectiveWrapper
将$scope.mymodel
作为范围,而不是其他任何内容。然后我可以将指令放两次,指向不同的属性。
我有一个带有问题的演示项目:http://jsfiddle.net/vtortola/P8JMm/3/
同样的演示工作正常(不限制范围):http://jsfiddle.net/vtortola/P8JMm
问题是,如何在使用我的指令时表明我想使用我的$scope
的特定属性作为我的指令的范围。应该可以将指令绑定到同一$scope
中的任意属性。
干杯。
答案 0 :(得分:2)
所以这个问题的基本答案是 - 你可以做你想做的事,但它比你想象的要复杂一些。要了解这里发生的事情,您需要了解角度范围。范围本质上是一个包含视图可访问数据的对象。有(至少)三种范围以角度运行的方式:
根据您的上述问题,您在此处要做的是扩展父作用域 - 将对象复制到新创建的子作用域中具有特定名称的属性。获得此行为的方法是在转换之前手动创建新的子范围。执行此操作的两个关键代码行是:
// create a "new" scope
var childScope = scope.$new();
// extend using the model binding provided
angular.extend(childScope, scope[iAttr.myModel]);
在您的指令的上下文中,这看起来像:
.directive('myDirectiveWrapper', ['$compile', function ($compile) {
return {
transclude: true,
restrict: 'E',
compile: function (element, attrs, transclude) {
var contents = element.contents().remove();
var compiledContents;
return function(scope, iElement, iAttr) {
var childScope = scope.$new();
angular.extend(childScope, scope[iAttr.myModel]);
if (!compiledContents) {
compiledContents = $compile(contents, transclude);
}
compiledContents(childScope, function(clone, childScope) {
iElement.append(clone);
});
};
},
template: "<div><h3>{{ name }}</h6><a class='back'>Back</a><div ng-transclude class='list'></div><a class='next'>Next</a>"
}
}])
现在,您可以指定任何您想要的变量作为&#34;模型&#34;对于子范围,您可以直接在转换代码的内容中访问它!
查看好消息: http://jsfiddle.net/P8JMm/7/
编辑:为了好玩,我为这个指令创建了一个更复杂的用例:http://jsfiddle.net/P8JMm/9/
注意 - 角度网站也有一些非常好的资源来更好地了解范围。 See here
答案 1 :(得分:1)
如果你想要双向绑定工作,那么在指令范围内创建一个变量要容易得多,而不是直接将mymodel
应用到指令范围。
<强> HTML 强>
<div ng-app="myapp">
<div ng-controller="myController">
<my-directive-wrapper model="mymodel">
<my-directive-inner ng-repeat="item in mymodel.items" />
</my-directive-wrapper>
</div>
</div>
<强>指令强>
.directive("myDirectiveWrapper", function(){
return {
scope: {
model: '='
},
restrict: 'E',
transclude: true,
link: function(scope, element, attrs, controller) {
},
template: "<div><h3>{{ model.name }}</h6><a class='back'>Back</a><div ng-transclude class='list'></div><a class='next'>Next</a>"
}
})
如果你不关心双向绑定我想你可以做这样的事情,但我不推荐它:
.directive("myDirectiveWrapper", function(){
return {
scope: {
model: '='
},
restrict: 'E',
transclude: true,
link: function(scope, element, attrs, controller) {
angular.extend(scope, scope.model);
},
template: "<div><h3>{{ name }}</h6><a class='back'>Back</a><div ng-transclude class='list'></div><a class='next'>Next</a>"
}
})
以下是第二种方法何时可能导致问题的示例。请注意,当您在输入字段中输入内容时,它将更改指令的名称,但不会更改外部范围中的名称:http://jsfiddle.net/r5JeJ/