我的代码是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']"});