我制作了一个小角度模块,以便与bootstrap" buttons-group" (' s加上一些javascript使它们像单选按钮一样工作。我在这个模块上做了同样的复选框:http://jsfiddle.net/evaneus/z9rge/
我的代码位于http://jsfiddle.net/askbjoernhansen/YjMMD/
我的问题:
1)这是正确的做法吗?
2)模型是否会被观看三次,或者是$ scope。$ watch()发现它是同一个型号,只做一次?似乎就是这样。
3)它是否正确"像我一样在$ watch函数中使用DOM进行捣乱?它感觉“肮脏的”#34;但是我猜这是我要求的,当我将角度添加到本地不兼容的角度时。或?
4)有没有办法将ng-model属性放在btn-group而不是每个按钮上?这使它显得更加清洁。
你可以在我上面的jsfiddle中看到它,或者代码在这里,首先是html:
<!-- to test the two-way model -->
<input name="test" type="radio" ng-model="myModel['A']" value="left"> Left<br>
<input name="test" type="radio" ng-model="myModel['A']" value="middle"> Middle<br>
<input name="test" type="radio" ng-model="myModel['A']" value="right"> Right<br>
myModel A {{myModel['A']}}<br/>
<div class="btn-group" data-toggle="buttons-radio">
<button type="button" buttons-radio=""
ng-model="myModel['A']" value="left" class="btn">Left</button>
<button type="button" buttons-radio=""
ng-model="myModel['A']" value="middle" class="btn">Middle</button>
<button type="button" buttons-radio=""
ng-model="myModel['A']" value="right" class="btn">Right</button>
</div>
和javascript:
angular.module('buttonsRadio', []).directive('buttonsRadio', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function($scope, element, attr, ctrl) {
element.bind('click', function() {
$scope.$apply(function(scope) {
ctrl.$setViewValue(attr.value);
});
});
// This should just be added once, but is added for each radio input now?
$scope.$watch(attr.ngModel, function(newValue, oldValue) {
element.parent(".btn-group").find('button').removeClass("active");
element.parent(".btn-group")
.find("button[value='" + newValue + "']").addClass('active');
});
}
};
});
答案 0 :(得分:26)
您正在调用该指令三次,每个按钮一次。 AFAIK这意味着链接功能被调用三次,绑定事件并观察变化。 在下面添加了更多内容。
在模型更改时更改DOM是很好的,但您正在做的事情 - 更改类和值 - 可以通过角度使用双向数据绑定和本机指令(如{)自动完成{1}}
您可以创建一个指令,根据选项列表呈现按钮。例如,如果您有此模型和这些选项
ng-class
您可以像这样创建一个$scope.myOptions = ["Left", "Middle", "Right"];
$scope.myModel = "Left"
指令
buttons-radio
可以从您的HTML
中调用App.directive('buttonsRadio', function() {
return {
restrict: 'E',
scope: { model: '=', options:'='},
controller: function($scope){
$scope.activate = function(option){
$scope.model = option;
};
},
template: "<button type='button' class='btn' "+
"ng-class='{active: option == model}'"+
"ng-repeat='option in options' "+
"ng-click='activate(option)'>{{option}} "+
"</button>"
};
});
需要注意的事项:
<buttons-radio class="btn-group" data-toggle="buttons-radio"
model='myModel'
options='myOptions'>
</buttons-radio>
指令,该指令遍历所有选项并相应地编译按钮。ng-repeat
和model
以接受双向绑定,因此当指令更改其值时,angular会发挥其魔力。options
类。active
(来自指令控制器),并更改模型的值。这是一个JSFiddle http://jsfiddle.net/jaimem/A5rvg/4/
修改强>
我对此并不完全确定,但是,您的模型将有三个不同的观察者,每个指令调用一个。如果您使用的是Batarang,则可以从 Performance 选项卡和 AngularJS Properties 面板中查看所有观察到的表达式。 Batarang还公开了activate
便利属性,因此您可以通过从控制台运行以下内容来查找模型的监视对象
$scope
答案 1 :(得分:7)
这很简单
<html>
<div class="btn-group" data-toggle="buttons">
<span class="btn btn-primary" ng-click="worktype=1" ng-class="worktype==1?'active':''">
<input type="radio" value="1">全职
</span>
<span class="btn btn-primary" ng-click="worktype=2" ng-class="worktype==2?'active':''">
<input type="radio" value="2">兼职
</span>
</div>
</html>