Bootstrap"buttons-radio"用AngularJS切换

Ask*_*sen 19 jquery twitter-bootstrap angularjs

我创建了一个小角度模块来集成引导程序"buttons-group"(加上一些javascript使它们像单选按钮一样工作.我在这个模块上做了同样的复选框:http:// jsfiddle达网络/ evaneus/z9rge /

我的代码在http://jsfiddle.net/askbjoernhansen/YjMMD/

我的问题:

1)这是正确的方法吗?

2)模型是否会被观看三次,或者是$ scope.$ watch()发现它是同一个型号而且只做一次?这似乎是这样的.

3)像我一样在$ watch函数中使用DOM来解决这个问题是否"正确"?它感觉"很脏",但我猜这就是我要求的时候我将角度添加到本机不兼容的angularjs.要么?

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>
Run Code Online (Sandbox Code Playgroud)

和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');
            });
        }
    };
});?
Run Code Online (Sandbox Code Playgroud)

jai*_*ime 26

您正在调用该指令三次,每个按钮一次.AFAIK这意味着链接功能被调用三次,绑定事件并观察变化.在下面添加了一点.

在模型更改时更改DOM是很好的,但您正在做的事情 - 更改类和值 - 可以通过角度使用双向数据绑定和本机指令(如ng-class

您可以创建一个指令,用于呈现给定选项列表的按钮.例如,如果您有此模型和这些选项

$scope.myOptions = ["Left", "Middle", "Right"];
$scope.myModel = "Left"
Run Code Online (Sandbox Code Playgroud)

您可以创建这样的buttons-radio指令

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>"
    };
});?
Run Code Online (Sandbox Code Playgroud)

可以从您的HTML调用

<buttons-radio class="btn-group" data-toggle="buttons-radio" 
               model='myModel'    
               options='myOptions'>
</buttons-radio>
Run Code Online (Sandbox Code Playgroud)

需要注意的事项:

  1. 该模板使用一个ng-repeat指令,该指令遍历所有选项并相应地编译按钮.
  2. 该指令有自己的控制器和隔离范围,model并且options接受双向绑定,因此当指令更改其值时,angular会发挥其魔力.
  3. 如果该选项与模型的当前值匹配,则为该按钮分配一个active类.
  4. 按下按钮时,将activate调用方法(来自指令控制器),并更改模型的值.

继承人JSFiddle http://jsfiddle.net/jaimem/A5rvg/4/


编辑

我对此并不完全确定,但是,您的模型将有三个不同的观察者,每个指令调用一个.如果您使用的是Batarang,则可以从" 性能"选项卡和" AngularJS属性"面板中查看所有已观察的表达式.Batarang还公开了一个$scope便利属性,因此您可以通过从控制台运行以下内容来查找模型的监视对象

$scope.$$watchers.filter(function(w){return w.exp ==="myModel['A']"}); 
Run Code Online (Sandbox Code Playgroud)

  • 很好,谢谢!但是,使用Twitter Bootstrap 3时,未设置"活动"类.任何洞察力为什么?更新了小提琴:http://jsfiddle.net/A5rvg/79/ (2认同)

小智 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>
Run Code Online (Sandbox Code Playgroud)