我的代码是http://jsfiddle.net/askbjoernhansen/YjMMD/
我的问题:
1)这是正确的做法吗?
2)模型将被观看三次,或者是范围。$ watch()确定它是相同的模型,只是做一次?好像这样
3)像我一样,在$ watch功能中,DOM是否“正确”?感觉“肮脏”,但是我猜这是我正在要求的,当我添加角度与本来不相关的角度。要么?
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');
});
}
};
});
解决方法
在模型更改时更改DOM,但您正在做的 – 改变类和值 – 可以通过使用双向数据绑定和本地指令(如ng-class)的角度自动完成DOM
您可以创建一个指令,使指令列表中的按钮呈现。例如,如果你有这个模型和这些选项
$scope.myOptions = ["Left","Middle","Right"]; $scope.myModel = "Left"
您可以创建这样的按钮无线电指令
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>"
};
});
这可以从您的HTML中调用
<buttons-radio class="btn-group" data-toggle="buttons-radio"
model='myModel'
options='myOptions'>
</buttons-radio>
注意事项:
>该模板使用一个ng-repeat指令,通过所有选项,并相应地编译按钮。
>该指令具有自己的控制器和隔离的范围,具有模型和选项以接受双向绑定,因此当指令更改其值时,角度具有魔力。
>如果该选项与模型的当前值相匹配,则该按钮被分配一个活动类。
>当按下按钮时,调用方法activate(从指令控制器),并更改模型的值。
亲爱的JSfiddle http://jsfiddle.net/jaimem/A5rvg/4/
编辑
我不完全确定这一点,但是,您的模型将有三个不同的观察者,每个指令调用一个。如果使用Batarang,您可以从“性能”选项卡和“角度属性”面板查看所有观察到的表达式。 Batarang还公开了一个$ scope便利属性,因此您可以通过从控制台运行以下内容来查找模型的watch对象
$scope.$$watchers.filter(function(w){return w.exp ==="myModel['A']"});