假设我有一个看起来像这样的指令:
directive('attachment', function() {
return {
restrict: 'E',
controller: 'AttachmentCtrl'
}
})
这意味着我可以编写一个“附件”元素列表,如下所示:
<attachment ng-repeat="a in note.getAttachments()">
<p>Attachment ID: {{a.id}}</p>
</attachment>
在上面的代码片段中,我们假设note.getAttachments()
返回一组简单的javascript对象哈希值。
因为我为指令设置了一个控制器,所以我可以内联调用该控制器的作用域函数。
这是控制器:
function AttachmentCtrl($scope) {
$scope.getFilename = function() {
return 'image.jpg';
}
}
以下是当我们对$scope.getFilename
函数内联(新的第2段)进行调用时修改后的HTML:
<attachment ng-repeat="a in note.getAttachments()">
<p>Attachment ID: {{a.id}}</p>
<p>Attachment file name: {{getFilename()}}
</attachment>
但是,这没用。这将只打印相同的字符串“image.jpg”作为每个附件的文件名。
实际上,附件的文件名基于附件ID。因此ID为“2”的附件的文件名为“image-2.jpg”。
因此需要修改我们的getFilename
函数。我们来解决它:
function AttachmentCtrl($scope) {
$scope.getFilename = function() {
return 'image-' + a.id + '.jpg';
}
}
但等等 - 这不行。范围中没有变量a
。由于a
,我们可以使用变量ng-repeat
内联,但a
变量不适用于绑定到指令的范围。
所以问题是,如何让范围内的a
可用?
请注意:我意识到在这个特定的例子中,我可以打印image-{{a.id}}.jpg
内联。但这并没有回答这个问题。这只是一个极其简化的例子。实际上,getFilename
函数太复杂了,无法内联打印。
编辑:是的,getFilename
可以接受一个参数,这样就行了。但是,这也没有回答这个问题。我仍然想知道,没有解决方法,是否可以在不使用内联的情况下将a
放入范围。
例如,可能有一种方法可以将其直接注入控制器,因此它将被写为:
function AttachmentCtrl($scope, a) { ... }
但是我会从哪里传递它?我可以在指令声明中添加一些内容吗?也许我可以在ng-repeat旁边添加一个ng- *属性?我只是想知道它是否可能。
答案 0 :(得分:2)
另一种方法是使用ng-init
并为子范围设置模型属性。见fiddle
相关代码将是
<div ng-app='myApp' ng-controller='MyCtrl'>
<attachment ng-repeat="a in attachments" ng-init='model=a'>
<p>Attachment ID: {{model.id}}</p>
<p>Attachment file name: {{getFilename()}}</p>
</attachment>
</div>
和
function AttachmentCtrl($scope) {
$scope.getFilename = function () {
return 'image-' + $scope.model.id + '.jpg';
}
}
答案 1 :(得分:2)
但等等 - 这不行。范围中没有变量“a”。我们可以使用变量a inline得益于 ng-repeat,但是变量不适用于绑定的范围 指令。
实际上,变量a
位于与指令控制器关联的范围内。由指令创建的每个控制器获取由ng-repeat迭代创建的子范围。这样可行(注意 $ scope .a.id):
function AttachmentCtrl($scope) {
$scope.getFilename = function() {
return 'image-' + $scope.a.id + '.jpg';
}
这是一个显示控制器范围,指令范围和ngRepeat范围的fiddle。
“如果同一元素上的多个指令请求新范围,则只创建一个新范围。” - Directive docs,“指令定义对象”部分
在您的示例中,ng-repeat正在创建一个新范围,因此该同一元素上的所有指令都会获得相同的新(子)范围。
另外,如果您遇到需要将变量放入控制器的情况,使用属性会比使用ng-init更好。
答案 2 :(得分:0)
将它传递给你的函数。
查看:强>
<attachment ng-repeat="a in note.getAttachments()">
<p>Attachment ID: {{ a.id }}</p>
<p>Attachment file name: {{ getFilename(a) }}
</attachment>
<强>控制器强>:
function AttachmentCtrl ($scope) {
$scope.getFilename = function (a) {
return 'image-' + a.id + '.jpg';
}
}