我可以在ng-repeat循环中避免对象变量名吗?

时间:2013-04-04 12:11:13

标签: javascript angularjs angularjs-scope angularjs-ng-repeat

定义ng-repeat指令迭代数组时,语法指定ng-repeat="friend in friends",然后在模板中使用interoplation运算符,如{{friend.name}}

是否可以将属性分配给当前项目范围,而不是其中的变量?所以我只能拨打{{name}}而不是{{friend.name}}

原因是我的指令正在两个不同模板的范围内使用 - 例如,我可能有一个指令"userActions",它在转发器中使用,也在一个不相关的模板中使用{{ 1}}没有意义。我想避免人为地制造没有语义含义的{{friend.name}}对象。


我的用例是这样的:

我有一个网格,可以渲染各种类型的块。一些伪代码:

friend

我还有一个朋友页面,其中包含完全相同的用户操作:

<div ng-repeat="block in blocks">
   < cat block />

   < friend block >
         <userActions directive />
   </ friend block >

   < guitar block />

   .... more blocks
</div>

现在,如果我想在转发器中使用块的属性,则语法为..fragment of friend page.. <element ng-control="friend"> <userActions directive /> </element> 。因此{{block.name}}的模板包含此内容。

但是,一旦我在 friend 页面中使用此模板,我必须在朋友控制器的范围内创建userActions。但这没有意义,因为块仅存在于块网格的上下文中。我不应该创建这个{{block.name}}

我希望能够做的只是从block指令模板中调用{{name}},因为块作用域和控制器都包含它。我不想创建userActions对象,然后在我想要使用block指令的每个范围内人工设置block.name

这是jsFiddle to illustrate the cause

2 个答案:

答案 0 :(得分:2)

我决定将Mathew Bergganaraj的信息性答案与我新发现的知识结合起来,为此创造一个有用的答案。

简短的回答是你真的不想这样做


答案越长越好:

使用ng-repeat="block in blocks时,会为每个块元素创建一个新范围,并且每个块对象的属性都在每个块的scope.block中创建。这是一件好事,因为这意味着所有属性都可以通过引用,更新或$ watch来访问。

如果ng-repeat没有这样做,并且所有属性都只是被打到了块的范围,那么block中的所有原语(字符串,整数等)都只会从阻止对象到块作用域对象。一个变化不会反映在另一个上,这很糟糕。 More info on that here.

好的,现在我们已经确定这是一件好事而不是坏事,我们如何克服语义问题?我决定使用friendData对象容器作为我的指令范围内的对象,因此指令期望friend-data属性保存相关属性

angular.module('myApp',[])
.directive("lookActions", function(){
    return {              
        restrict: 'E',        
        template: "<input value='Kill -{{ friendData.name }}-' type='button'>",
        scope : {
            friendData : '='            
        }
    }
});

这样我就可以分配这个对象,无论我在哪个上下文中调用我的指令模板。

鉴于这些控制器上下文:

function gridCtrl($scope) {    
    $scope.blocks = [{ type: "cat", name: "mitzi"},{ type: "friend", name: "dave"},{ type: "guitar", name: "parker"}];
}


function friendCtrl($scope) {    
    $scope.data={
        name: "dave"
    }
}

如何调用指令 -

ng-repeat内:

    <div class="block" ng-repeat="block in blocks" >            
        <look-actions friend-data="block" />
    </div>

或者在不同的背景下:

    <div ng-controller="friendCtrl">  
         <look-actions friend-data="data" />
     </div>

这是solution Fiddle

感谢您的帮助!

答案 1 :(得分:1)

这一切都取决于你如何构建你的指令。很难说没有小提琴/傻瓜你的代码是什么样的,所以我在黑暗中捅了一下。现在我想你要说的是,在你使用你的指令friend.name的情况下,没有意义。也许像person.name这样更通用的东西可能更合适。在这种情况下,您可以执行以下操作,以便将要与该人员关联的指令传递给指令:

<强> HTML

<div data-ng-repeat="friend in friends">
    {{ friend.name }}
    <div class="myDirective" data-person="friend"></div>
</div>

<强>的javascript

.directive("myDirective", function(){
    return {
        restrict: 'C',
        scope: {
            person: "=person"
        },
        template: "<div>{{ person.name }}</div>"

    }
});

jsfiddle http://jsfiddle.net/5aVLf/1/