AngularJS 지시문의 확인란 클릭에 응답하는 방법은 무엇입니까?
다음 템플릿에서 엔티티 컬렉션을 렌더링 하는 AngularJS 지시문 이 있습니다.
<table class="table">
<thead>
<tr>
<th><input type="checkbox" ng-click="selectAll()"></th>
<th>Title</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="e in entities">
<td><input type="checkbox" name="selected" ng-click="updateSelection($event, e.id)"></td>
<td>{{e.title}}</td>
</tr>
</tbody>
</table>
보시다시피 <table>
각 행을 자체 체크 박스를 사용하여 개별적으로 선택하거나에있는 마스터 체크 박스를 사용하여 한 번에 모든 행을 선택할 수 있습니다 <thead>
. 꽤 고전적인 UI.
다음을 수행하는 가장 좋은 방법은 무엇입니까?
- 단일 행을 선택
<tr>
합니까 (예 : 확인란이 선택되면 선택한 엔티티의 ID를 내부 배열에 추가 하고 엔티티를 포함 하는 CSS 클래스를 추가하여 선택한 상태를 반영)? - 한 번에 모든 행을 선택 하시겠습니까? (예 :의 모든 행에 대해 이전에 설명한 작업 수행
<table>
)
내 현재 구현은 내 지시문에 사용자 지정 컨트롤러를 추가하는 것입니다.
controller: function($scope) {
// Array of currently selected IDs.
var selected = $scope.selected = [];
// Update the selection when a checkbox is clicked.
$scope.updateSelection = function($event, id) {
var checkbox = $event.target;
var action = (checkbox.checked ? 'add' : 'remove');
if (action == 'add' & selected.indexOf(id) == -1) selected.push(id);
if (action == 'remove' && selected.indexOf(id) != -1) selected.splice(selected.indexOf(id), 1);
// Highlight selected row. HOW??
// $(checkbox).parents('tr').addClass('selected_row', checkbox.checked);
};
// Check (or uncheck) all checkboxes.
$scope.selectAll = function() {
// Iterate on all checkboxes and call updateSelection() on them??
};
}
더 구체적으로 궁금합니다.
- 위의 코드가 컨트롤러에 속합니까 아니면
link
함수에 들어가야 합니까? - jQuery가 반드시 존재하는 것은 아니라는 점을 감안할 때 (AngularJS에서는 필요하지 않음) DOM 탐색을 수행하는 가장 좋은 방법은 무엇입니까? jQuery가 없으면
<tr>
주어진 확인란 의 부모 를 선택하거나 템플릿의 모든 확인란을 선택하는 데 어려움을 겪습니다. - 에 전달
$event
하는updateSelection()
것은 매우 우아하게 보이지 않습니다. 방금 클릭 한 요소의 상태 (선택 / 선택 해제)를 검색하는 더 좋은 방법이 없습니까?
감사합니다.
이것이 제가 이런 일을 해왔 던 방식입니다. Angular는 명령적인 것보다는 dom의 선언적인 조작을 선호하는 경향이 있습니다 (적어도 내가 가지고 놀던 방식입니다).
마크 업
<table class="table">
<thead>
<tr>
<th>
<input type="checkbox"
ng-click="selectAll($event)"
ng-checked="isSelectedAll()">
</th>
<th>Title</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="e in entities" ng-class="getSelectedClass(e)">
<td>
<input type="checkbox" name="selected"
ng-checked="isSelected(e.id)"
ng-click="updateSelection($event, e.id)">
</td>
<td>{{e.title}}</td>
</tr>
</tbody>
</table>
그리고 컨트롤러에서
var updateSelected = function(action, id) {
if (action === 'add' && $scope.selected.indexOf(id) === -1) {
$scope.selected.push(id);
}
if (action === 'remove' && $scope.selected.indexOf(id) !== -1) {
$scope.selected.splice($scope.selected.indexOf(id), 1);
}
};
$scope.updateSelection = function($event, id) {
var checkbox = $event.target;
var action = (checkbox.checked ? 'add' : 'remove');
updateSelected(action, id);
};
$scope.selectAll = function($event) {
var checkbox = $event.target;
var action = (checkbox.checked ? 'add' : 'remove');
for ( var i = 0; i < $scope.entities.length; i++) {
var entity = $scope.entities[i];
updateSelected(action, entity.id);
}
};
$scope.getSelectedClass = function(entity) {
return $scope.isSelected(entity.id) ? 'selected' : '';
};
$scope.isSelected = function(id) {
return $scope.selected.indexOf(id) >= 0;
};
//something extra I couldn't resist adding :)
$scope.isSelectedAll = function() {
return $scope.selected.length === $scope.entities.length;
};
수정 :getSelectedClass()
expects the entire entity but it was being called with the id of the entity only, which is now corrected
확인란을 다룰 때 ngModel 및 ngChange 지시문 을 사용하는 것을 선호합니다 . ngModel을 사용하면 확인란의 선택 / 선택 취소 상태를 엔티티의 속성에 바인딩 할 수 있습니다.
<input type="checkbox" ng-model="entity.isChecked">
사용자가 확인란을 선택하거나 선택 취소 할 때마다 entity.isChecked
value will change too.
이것이 필요한 전부라면 ngClick 또는 ngChange 지시문도 필요하지 않습니다. "모두 확인"확인란이 있으므로 누군가가 확인란을 선택할 때 속성 값을 설정하는 것 이상을 수행해야합니다.
When using ngModel with a checkbox, it's best to use ngChange rather than ngClick for handling checked and unchecked events. ngChange is made for just this kind of scenario. It makes use of the ngModelController for data-binding (it adds a listener to the ngModelController's $viewChangeListeners
array. The listeners in this array get called after the model value has been set, avoiding this problem).
<input type="checkbox" ng-model="entity.isChecked" ng-change="selectEntity()">
... and in the controller ...
var model = {};
$scope.model = model;
// This property is bound to the checkbox in the table header
model.allItemsSelected = false;
// Fired when an entity in the table is checked
$scope.selectEntity = function () {
// If any entity is not checked, then uncheck the "allItemsSelected" checkbox
for (var i = 0; i < model.entities.length; i++) {
if (!model.entities[i].isChecked) {
model.allItemsSelected = false;
return;
}
}
// ... otherwise ensure that the "allItemsSelected" checkbox is checked
model.allItemsSelected = true;
};
Similarly, the "Check All" checkbox in the header:
<th>
<input type="checkbox" ng-model="model.allItemsSelected" ng-change="selectAll()">
</th>
... and ...
// Fired when the checkbox in the table header is checked
$scope.selectAll = function () {
// Loop through all the entities and set their isChecked property
for (var i = 0; i < model.entities.length; i++) {
model.entities[i].isChecked = model.allItemsSelected;
}
};
CSS
What is the best way to... add a CSS class to the
<tr>
containing the entity to reflect its selected state?
If you use the ngModel approach for the data-binding, all you need to do is add the ngClass directive to the <tr>
element to dynamically add or remove the class whenever the entity property changes:
<tr ng-repeat="entity in model.entities" ng-class="{selected: entity.isChecked}">
See the full Plunker here.
Liviu's answer was extremely helpful for me. Hope this is not bad form but i made a fiddle that may help someone else out in the future.
Two important pieces that are needed are:
$scope.entities = [{
"title": "foo",
"id": 1
}, {
"title": "bar",
"id": 2
}, {
"title": "baz",
"id": 3
}];
$scope.selected = [];
'Program Tip' 카테고리의 다른 글
보고서에 매개 변수 (다중 값) 표시 (0) | 2020.10.09 |
---|---|
Python을 사용하여 Selenium에서 자바 스크립트 실행 (0) | 2020.10.09 |
비어 있지 않은 속성에 대한 CSS 속성 선택기 (0) | 2020.10.09 |
Mac OS 10.10 이상에서 GNU sed를 사용하는 방법, 'brew install --default-names'더 이상 지원되지 않음 (0) | 2020.10.09 |
두 문자열을 연결하여 완전한 경로를 만드는 방법 (0) | 2020.10.09 |