gpt4 book ai didi

带有 ng-repeat 的 AngularJS 指令不呈现

转载 作者:行者123 更新时间:2023-12-04 11:08:53 25 4
gpt4 key购买 nike

问题是我必须管理从服务中检索到的口香糖球列表。当我对 HTML 中的元素进行硬编码时,我创建的指令似乎有效,但是当我尝试使用 ng-repeat 动态分配口香糖球时。

HTML

<div ng-controller="GumballsCtrl">

<h1>Working</h1>
<ul>
<li ng-repeat="gumball in Gumballs">
<div class="gumballColor{{gumball.color}}">{{gumball.color}}</div>
</li>
</ul>

<h1>Problem - Expecting the same result at the work version</h1>

<ul>
<li ng-repeat="gumball in Gumballs">
<mygumball id={{gumball.id}} color="{{gumball.color}}">{{gumball.color}}</mygumball>
</li>
</ul>
</div>

JavaScript
var myApp = angular.module('myApp', []);

function GumballsCtrl($scope, Gumballs) {
$scope.Gumballs = Gumballs;
}

myApp.factory('Gumballs', function () {
return [{
id: '1',
color: 'R'
}, {
id: '2',
color: 'G'
}, {
id: '3',
color: 'B'
}, {
id: '4',
color: 'Y'
}, {
id: '5',
color: 'G'
}];
});

myApp.directive('mygumball', function ($scope) {
return {
restrict: 'E',

scope: {},

link: function (scope, element, attrs) {
if (attrs.color !== '' && attrs.color !== undefined) {
scope.color = attrs.color;
} else {
scope.color = 'U';
}
},

replace: true,

template: "<div class='gumballColor{{color}}'>{{color}}</div>"
};
});

CSS
.gumballColorR {
font-size: 12px;
text-align: center;
padding: 2px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
border: solid 1px #CC0000;
background-color: #FF0000;
width: 15px;
height: 15px;
margin-left: 5px;
margin-top: 5px;
}
.gumballColorG {
font-size: 12px;
text-align: center;
padding: 2px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
border: solid 1px #00CC00;
background-color: #00FF00;
width: 15px;
height: 15px;
margin-left: 5px;
margin-top: 5px;
}
.gumballColorB {
font-size: 12px;
text-align: center;
padding: 2px;
color: #FFFFFF;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
border: solid 1px #0000CC;
background-color: #0000FF;
width: 15px;
height: 15px;
margin-left: 5px;
margin-top: 5px;
}
.gumballColorY {
font-size: 12px;
text-align: center;
padding: 2px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
border: solid 1px #CCCC00;
background-color: #FFFF00;
width: 15px;
height: 15px;
margin-left: 5px;
margin-top: 5px;
}
.gumballColorU {
font-size: 12px;
text-align: center;
padding: 2px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
border: solid 1px #CCCCCC;
background-color: #DDDDDD;
width: 15px;
height: 15px;
margin-left: 5px;
margin-top: 5px;
}

http://jsfiddle.net/i3sik/NGB9v/22/

传入指令时的 id 和 color 属性在使用 ng-repeat 传递时最终是未定义的,但在 HTML 中硬编码时可以工作。

最佳答案

这里的问题是您的隔离范围。通过使用 scope: {}您创建了一个新的隔离范围来作用于该元素。隔离范围不会从父范围继承。具有隔离范围的指令上的所有属性和内容都在隔离范围的上下文中进行评估。 gumball不存在于隔离范围内,所以一切都是未定义的。

您有两种选择来解决此问题: (1) 删除隔离范围(例如 scope: true 以创建子范围);或 (2) 绑定(bind)隔离范围内的值。

要将属性绑定(bind)到范围变量,您只需指定范围和所需的绑定(bind)类型:

scope: {
id: '@',
color: '@'
},

这表示属性 idcolor将在父范围的上下文中进行插值,然后添加到范围中。您可以删除 link 中的所有逻辑。功能 - 这将为您完成。

但这仍然留下了指令内部内容的问题。要在父范围的上下文中插入它,您需要嵌入:

transclude: true,
template: "<div class='gumballColor{{color}}' ng-transclude></div>"

嵌入获取元素的内容并相对于父作用域的新子元素进行插值,例如在哪里 gumball仍将被定义。

通过这两个更改,您的指令将按需要工作。

如果您对使用哪个范围感到困惑,这里有另一个可能会有所帮助的 SO 问题: When writing a directive, how do I decide if a need no new scope, a new child scope, or a new isolate scope?

旁注:即使没有隔离范围, link 中的逻辑确定属性值的函数不起作用。执行顺序是这里的重要部分,大致是:编译器 -> Controller -> 链接 -> 插值。在插值完成之前,您的属性没有任何值(value)。所以你的支票是行不通的。

也就是说,您可以设置 $observe关于内插属性; $observe总是第一次触发,即使没有传递任何值。您可以使用它来设置默认值。 $observe效率也很高。

attrs.$observe( 'attr1', function(val) {
if ( !angular.isDefined( val ) ) {
scope.attr1 = 'defaultValue';
}
});

关于带有 ng-repeat 的 AngularJS 指令不呈现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15827194/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com