<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>
我在link中可以更改checked并影响视图,实现点击全选的功能,
但是其实我也可以向下面这样
<li select-all boxWrap=".checkbox">全选</li>
<p class="checkbox">
<input type="checkbox" >
<input type="checkbox">
<input type="checkbox">
</p>
然后在directive的link中拿到 .checkbox 然后使用jq先拿到p.checkbox 然后将input[type=checkbox]
一次设置成checked ,反选的时候类似
这种方案我更喜欢第二种,我觉得可能不会产生太多的$watch, 但是我觉得第二种方法 设置类名作为dirctive
的属性好像就是 拐了个弯来使用 jq。
有没有好的建议,或者其他实现方法。
为情所困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.