<li select-all status="checked">全选</li>
<p>
<input type="checkbox" ng-checked="checked" ng-model="checked">
<input type="checkbox" ng-checked="checked" ng-model="checked">
<input type="checkbox" ng-checked="checked" ng-model="checked">
</p>
I can change checked in the link and affect the view to achieve the function of clicking to select all,
But actually I can also look like this
<li select-all boxWrap=".checkbox">全选</li>
<p class="checkbox">
<input type="checkbox" >
<input type="checkbox">
<input type="checkbox">
</p>
Then get .checkbox in the link of the directive and then use jq to get p.checkbox first and then input[type=checkbox]
Once set to checked, when unchecked it is similar to
I prefer the second solution. I think it may not generate too many $watches, but I think the second method is to set the class name as direct
The properties seem to be a roundabout way to use jq.
Are there any good suggestions or other ways to achieve this?
为情所困2017-05-15 16:54:09
The first method is actually very bad, because too much ng-checked will generate a large number of $watchers on the same scope. affect performance.
You can look at the source code of angular ng-checked
for this
javascript
// boolean attrs are evaluated forEach(BOOLEAN_ATTR, function(propName, attrName) { // binding to multiple is not supported if (propName == "multiple") return; var normalized = directiveNormalize('ng-' + attrName); ngAttributeAliasDirectives[normalized] = function() { return { restrict: 'A', priority: 100, link: function(scope, element, attr) { scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) { attr.$set(attrName, !!value); }); } }; }; });
You can see that there are as many $watchers as there are ng-checked. It's definitely not a best practice to do this.
The second method is really not good as you said (don’t expose the idea of dom operation to the view, it won’t work at all).
Analyze the demand. In fact, this demand is analyzed into the idea of angular model. It can be like this.
Select all button -> A
checkbox1 -> A1
checkbox2 -> A2
checkbox3 -> A3
checkbox4 -> A4
When the value of A's model is (true value), the values of A1-A4model are changed to (true value); then execution in the instruction triggers the $digest loop. so. Don’t change all checkboxes. This way $watcher will not be generated. And the goal of selecting all was achieved.
Give you a piece of code written casually:
html
<label checkbox-select-all group="['checkbox1', 'checkbox2', 'checkbox3']">全选</label> <p> <input type="checkbox" ng-model="checkbox1"> 1 <input type="checkbox" ng-model="checkbox2"> 2 <input type="checkbox" ng-model="checkbox3"> 3 </p>
javascript
directive('checkboxSelectAll', ['$parse', function($parse){ var linkFn = function(scope, element, attrs){ var group = $parse(attrs.group || '[]')(scope); element.on('click', function(){ scope.$apply(function(){ group.forEach(function(checkbox){ scope[checkbox] = true; }); }); }); }; return { restrict: 'A', link: linkFn } }])
In this case, the second situation you mentioned will not happen.
This form has strong scalability. (I can implement it when I have time) It can support category selection. (The above is just random code).
Actually, I think the questioner’s biggest confusion about this question may be because he is familiar with using DOM operations to solve problems. In fact, I used to be like this too. (I still do this sometimes). Very normal.
====================================
After get off work today, I implemented a draft version based on the envisioned model (implemented casually, lacking two-way binding). Put it on Plunker.
This version is a rough draft. There are many imperfections, such as ng-true-value
, ng-false-value
and other functions.
高洛峰2017-05-15 16:54:09
I personally feel that the first method is fine, but using the second method feels a bit complicated.