我有一个带有以下标记的select2下拉列表:
<select id="selectByName" ui-select2="select2Options" ng-model="selectId" data-placeholder="Select item by name" style="width:250px">
<option></option>
<option ng-repeat='item in items' data-show="{{item.show}}" value="{{item.id}}">
{{item.name}}
</option>
</select>
js包含以下内容:
$scope.items
(具有id,布尔show属性和name属性的数组)
和选择2选项:
select2Options : {
allowClear: true,
placeholder:"select a value",
formatResult: function(state) {
var $elem = angular.element(state.element),
isVisible = $elem.data('show');
return isVisible ? '<span style="color:red">'+state.text+'</span>':
<span style="color:blue">'+state.text+'</span>';
}
},
好吧,ng-repeat
正确更新了html标记,并将data-show属性设置为true或false,但formatResult
函数不更新此值。
在html源data-show="true"
和formatResult
函数$elem.data('show') = false;
中,为什么每次打开select2时调用函数都不会更新?
这是一个说明我问题的plunker:plnkr.co/edit/d0LxuhzdQh7hMdzOoxpr?p=preview。看起来formatResult只在第一次打开select2之前正确更新结果一次。
答案 0 :(得分:1)
修改强>
http://plnkr.co/edit/6Vma1WTQWQw0HAIQUVxE?p=preview
$scope.select2options = {
allowClear: true,
placeholder: "select a value",
formatResult: function(state, container) {
var $elem = angular.element(state.element);
var scope = $elem.data('$scope');
if (scope !== undefined) {
isVisible = scope.$eval($elem.data('show'));
$scope.dataShow[$elem.attr('value')] = isVisible;
$scope.updated++;
return isVisible ? '<span style="color:red">' + state.text + '</span>' :
' <span style="color:blue">' + state.text + '</span>'
}
}
}
关键部分是从jqLite元素中获取$scope
数据,然后调用$eval
,它会在范围的上下文中计算未解析的字符串表达式。如果我们使用了$scope.$eval
,它就会使用控制器$scope
,它不会有ng-repeat
。通过从元素中获取它,我们有一个范围可以访问item
的{{1}}属性。
说过我不建议使用这个代码(有时jQuery小部件会在处理角度时强迫你进入令人不快的角落)。再次,如果您发现自己在控制器中操纵ng-repeat
或使用angular.element
,则可能应该使用指令。然后,我们程序员必须处理阻止我们“理想”工作的非理想约束(时间,金钱等),因此根据您的上下文,这可能是一个不错的解决方案。
如果我的任何解释没有意义,请告诉我。
<强>原始强>
http://plnkr.co/edit/vYTdxPwgwqZSgK5m9yk9?p=preview
这是你想要的吗?
的JavaScript
$element
HTML 的
$scope.items = [{
id: 1,
show: false,
name: 'test1'
}, {
id: 2,
show: true,
name: 'test2'
}, {
id: 3,
show: true,
name: 'test3'
}];
$scope.selections = [1, 2];
$scope.getStyleForIndex = function (index) {
var item;
for (var i = 0; i < $scope.items.length; i++) {
if (i === index) {
item = $scope.items[i];
break;
}
}
return item.show ? { color: "red" } : { color: "blue" };
}
$scope.select2options = {
allowClear: true,
formatResult: function(item, container) {
var color = $scope.getStyleForIndex(parseInt(item.id, 10)).color;
container.html('<span style="color:' + color + '">RESULT ' + item.text + '</span>');
},
formatSelection: function(item, container) {
container.append($compile('<span ng-style="getStyleForIndex(' + item.id + ')">SELECTION ' + item.text + '</span>')($scope));
}
}