我可以避免 ng-repeat 循环中的对象变量名称吗? [英] Can I avoid the object variable name in ng-repeat loop?

查看:25
本文介绍了我可以避免 ng-repeat 循环中的对象变量名称吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当定义一个 ng-repeat 指令来迭代一个数组时,语法指定ng-repeat="friend infriends",然后在模板中你像这样使用互操作运算符{{friend.name}}.

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

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

<小时>

我的用例是这样的:

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

<猫块/><朋友块 ><userActions 指令/></朋友块><吉他块/>.... 更多块

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

..好友页面的片段..<元素 ng-control="朋友"><userActions 指令/></元素>

现在,如果我想在转发器中使用块的属性,语法是{{block.name}}.所以 userActions 的模板包含这个.

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

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

这是一个 jsFiddle 来说明原因

解决方案

我决定结合 Mathew 的信息性答案Bergganaraj 用我新发现的知识来创建一个有用的答案.

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

<小时>

更长的答案是:

当使用 ng-repeat="block in blocks" 时,会为每个块元素创建一个新的作用域,每个块对象的属性都在 scope.block 中创建每个块的代码>.这是一件好事,因为这意味着可以通过引用、更新或 $watched 访问所有属性.

如果 ng-repeat 不会这样做,并且所有属性都将被打到块的范围内,那么 block 中的所有原语(字符串、整数、等)只会从块对象复制到块范围对象.一个的改变不会影响另一个,这很糟糕.更多信息在这里.

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

angular.module('myApp',[]).directive("lookActions", function(){返回 {限制:'E',模板:<input value='Kill -{{friendData.name }}-' type='button'>",范围 : {朋友数据:'='}}});

这样我就可以分配这个对象,而不管我调用指令模板的上下文.

给定这些控制器上下文:

function gridCtrl($scope) {$scope.blocks = [{ type: "cat", name: "mitzi"},{ type: "friend", name: "dave"},{ type: "guitar", name: "parker"}];}功能朋友Ctrl($范围){$scope.data={姓名:戴夫"}}

如何调用指令 -

ng-repeat 中:

 

或者在不同的上下文中:

 

<look-actionsfriend-data="data"/>

这是解决方案小提琴

感谢大家的帮助!

When defining an ng-repeat directive to iterate over an array, the syntax specifies ng-repeat="friend in friends", and then within the template you use the interoplation operator like so {{friend.name}}.

Is it possible to have the properties assigned to the current item scope, rather than a variable in it? So I could call just {{name}} instead of {{friend.name}}?

The reason being is that my directive is being used in the scope of two different templates - for example I might have a directive "userActions" that is used in both a repeater, and also inside an unrelated template where {{friend.name}} doesn't make sense. I would like to avoid artificially manufacturing the friend object where it doesn't have a semantic meaning.


My use case is something like this:

I have a grid that renders blocks of various types. Some psuedo code:

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

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

   < guitar block />

   .... more blocks
</div>

I also have a friend page, that contains the exact same user actions:

..fragment of friend page..
  <element ng-control="friend">
     <userActions directive />
  </element>

Now, if I want to user a property of the block inside the repeater, the syntax is {{block.name}}. So the template for userActions contains this.

However, once I use this template in the friend page, I must create {{block.name}} inside the scope of the friend controller. This does not make sense though, because the block only exists in the context of the block grid. I shouldn't have to create this block.

What I want to be able to do, is just to call {{name}} from within the userActions directive template, since both the block scope and the controller contain it. I don't want to create a block object, then artificially set block.name in each scope where I want to use the userActions directive.

Here's a jsFiddle to illustrate the cause

解决方案

I've decided to combine the informative answers of Mathew Berg and ganaraj with my newfound knowledge to create a helpful answer to this.

The short answer is You really don't want to do that.


The longer answer is this:

When using ng-repeat="block in blocks" , a new scope is created for each block element, and the properties of every block object are create in scope.block of each block. This is a good thing, because this means all properties can be accessed by reference, updated or $watched.

If ng-repeat wouldn't have done that, and all properties would just be slapped unto the block's scope, then all primitives in block (strings, ints, etc) would just be copied from the block object to the block scope object. A change in one will not reflect on the other, and that's bad. More info on that here.

Ok so now that we've decided that's a good thing rather than a bad thing, how do we overcome the semantic issue? I've decided to use the friendData object container as the object on the scope of my directive, and so the directive expects the friend-data attribute to hold the relevant properties

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

This way I can assign this object regardless of which context I'm calling my directive template.

Given these controller contexts:

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


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

How to call the directive -

Within an ng-repeat:

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

Or in a difference context:

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

Here's the solution Fiddle

Thanks for all the help!

这篇关于我可以避免 ng-repeat 循环中的对象变量名称吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆