Angular Select2 formatResult не обновляет шаблон
У меня есть выпадающий 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
(массив с идентификатором, логическим свойством 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?
Вот сделанный поршень, который иллюстрирует мой вопрос: http://plnkr.co/edit/d0LxuhzdQh7hMdzOoxpr?p=preview. Похоже, formatResult корректно обновляет результаты только один раз, прежде чем открывать select2 в первый раз.
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>'
}
}
}
Ключевая часть захватывает $scope
данные из элемента jqLite, а затем вызов $eval
, который оценивает неразобранное строковое выражение в контексте области. Если бы мы использовали $scope.$eval
, он бы использовал контроллер $scope
что бы не иметь ng-repeat
в теме. Взяв его из элемента, мы получаем область, которая имеет доступ к item
собственность для ng-repeat
,
Сказав, что я не рекомендую использовать этот код (иногда виджеты jQuery вынуждают вас в неприятные углы при работе с angular). Опять же, если вы обнаружите, что манипулируете angular.element
или используя $element
в контроллере вы, вероятно, должны вместо этого использовать директиву. С другой стороны, нам, программистам, приходится иметь дело с неидеальными ограничениями (время, деньги и т. Д.), Которые мешают нам работать "идеально", поэтому, учитывая ваш контекст, это может быть достойным решением.
Дайте мне знать, если какое-либо из моих объяснений не имеет смысла.
оригинал
http://plnkr.co/edit/vYTdxPwgwqZSgK5m9yk9?p=preview
Это то, что вы хотите?
JavaScript
$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));
}
}
HTML
<div ng-repeat="item in items">
{{ item.name }}
<input type="checkbox" ng-model="item.show" />
</div>
<select ui-select2="select2options" ng-model="selections" style="width:200px" multiple="true" ng-options="i.id as i.name for i in items"></select>
{{selections}}