jquery - Bootstrap "buttons-radio"使用 AngularJS 切换

标签 jquery twitter-bootstrap angularjs

我制作了一个小的 Angular 模块来与 Bootstrap “buttons-group”集成(加上一些javascript,使它们像单选按钮一样工作。我在这个模块上做了同样的事情,对复选框进行同样的操作:http://jsfiddle.net/evaneus/z9rge/

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

我的问题:

1)这是正确的方法吗?

2) 模型会被观看三次,还是 $scope.$watch() 会发现它是同一个模型,然后只观看一次?好像是这样。

3) 像我一样在 $watch 函数中处理 DOM 是否“正确”?它感觉“肮脏”,但我想这就是我在将 Angular 添加到本来不兼容 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>

还有 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');
            });
        }
    };
});​

最佳答案

您将调用该指令三次,每个按钮调用一次。 AFAIK 这意味着链接函数被调用三次,绑定(bind)事件并观察变化。 在下面添加了更多内容。

模型更改时更改 DOM 很好,但是您正在做的事情 - 更改类和值 - 可以使用双向数据绑定(bind)和 native 指令(例如 ng-class)通过 Angular 自动完成

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

$scope.myOptions = ["Left", "Middle", "Right"];
$scope.myModel = "Left"

您可以创建这样的 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>"
    };
});​

可以从您的 HTML 调用

<buttons-radio class="btn-group" data-toggle="buttons-radio" 
               model='myModel'    
               options='myOptions'>
</buttons-radio>

注意事项:

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

这是一个 JSFiddle http://jsfiddle.net/jaimem/A5rvg/4/

<小时/>

编辑

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

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

关于jquery - Bootstrap "buttons-radio"使用 AngularJS 切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13448455/

相关文章:

javascript - Jquery如何在单击选项时设置参数?

jquery - 使用 jQuery 的 ASP.NET Web 服务的安全性

javascript - ng 类访问元素文本

html - 在angularJs中使用ng-class的问题

javascript - setTimeout 中的函数不会修改 $scope 变量/CSS 属性

javascript - HTML5 地理位置地址表单填充程序未捕获语法错误 : Unexpected token <

jquery - 使查询字符串可见

css - 覆盖字形以使用旧时尚背景属性

jquery - 更改 Bootstrap 表单元格中复选框的大小

javascript - Yii2:如果出现任何 yii2 错误,如何使 Bootstrap 选项卡处于事件状态