AngularJS:单选按钮不适用于Bootstrap 3

时间:2013-10-03 04:47:07

标签: javascript twitter-bootstrap angularjs angularjs-scope

我有一个单选按钮,根据交易类型的值设置TrueFalse的值

可以找到演示here

问题是当我点击任何一个单选按钮时,$scope.transaction.debit的值不会改变

我的javascript代码是

    var app = angular.module('myApp', []);

    app.controller("MainCtrl", function($scope){
      $scope.transaction = {};
      $scope.transaction.debit=undefined;

      console.log('controller initialized');
    });

请让我知道我做错了什么。

另外,我不想为此目的使用Angular-UIAngularStrap,除非没有其他选项可用。

9 个答案:

答案 0 :(得分:11)

我修改了dpineda's solution。您可以在不删除bootsrap.js依赖项的情况下使用。还有一个工作示例here

这是流程:

  1. 删除data-toggle="buttons"以防止引导执行。
  2. 添加一些CSS来修复损坏的视图(btn-radio css class)
  3. 为选中的样式效果添加一些AngularJS逻辑。
  4. <强> HTML

    <div class="btn-group col-lg-3">
      <label class="btn btn-default btn-radio" ng-class="{'active': transaction.debit == '0'}">
        <input type="radio" data-ng-model="transaction.debit" value="0"> Debit
      </label>
      <label class="btn btn-default btn-radio" ng-class="{'active': transaction.debit == '1'}">
        <input type="radio" data-ng-model="transaction.debit" value="1"> Credit
      </label>
    </div>
    
    <p>Transaction type: {{transaction.debit}}</p>
    

    <强>的JavaScript

    var app = angular.module('myApp', []);
    
    app.controller("MainCtrl", function($scope) {
    
      $scope.transaction = {
        debit: 0
      };
    });
    

    <强>风格

    .btn-radio > input[type=radio] {
      position       : absolute;
      clip           : rect(0, 0, 0, 0);
      pointer-events : none;
    }
    

答案 1 :(得分:5)

我在bootstrap.js中发现了问题。评论第e.preventDefault()行,它有效。

// BUTTON DATA-API
// ===============
$(document)
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
    var $btn = $(e.target)
    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
    Plugin.call($btn, 'toggle')
    e.preventDefault() //Before
    //e.preventDefault() //After
})
.on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
    $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
})

答案 2 :(得分:2)

您的单选按钮顶部有一个大标签,可防止输入您的单选按钮。 html应为:

 <input type="radio" data-ng-model="transaction.debit" value="True">Debit</input>

 <input type="radio" data-ng-model="transaction.debit" value="False">Credit</input>

然后它起作用,当然它可能看起来不像你想要的那样。

答案 3 :(得分:2)

如果删除de bootstrap代码,则可以使用条件

控制样式
<label class="btn btn-default" ng-class="{'active': transaction.debit == 'some'}">
    <input type="radio" data-ng-model="transaction.debit" name="debit" value="some"> Some
</label>
<label class="btn btn-default" ng-class="{'active': transaction.debit == 'other'}">
    <input type="radio" data-ng-model="transaction.debit" name="debit" value="other"> Other
</label>

答案 4 :(得分:1)

这是使用新指令的工作版本:

<强> HTML

<section ng-controller="MainCtrl">
<div class="form-group">
    <label class="col-lg-2 control-label">Type</label>

    <div class="btn-group col-lg-3" data-toggle="buttons">
        <label class="btn btn-default" radio-button ng-model="transaction.debit" value="True">
            Debit
        </label>
        <label class="btn btn-default" radio-button ng-model="transaction.debit" value="False">
            Credit
        </label>
    </div>

    <p>Transaction type: {{transaction.debit}}</p>
</div>
</section>

<强>的javascript

// Code goes here
var app = angular.module('myApp', []);

app.controller("MainCtrl", function($scope){
  $scope.transaction = {};
  $scope.transaction.debit=undefined;

  console.log('controller initialized');
});

app.directive("radioButton", function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attrs, ctrl) {
      element.bind('click', function () {
        if (!element.hasClass('active')) {
          scope.$apply(function () {
            scope.transaction.debit = attrs.value;
          });
        }
      });
    }
  };
})

答案 5 :(得分:1)

根据francisco.preller的回答,我写了两个解决方案,试图让它适合通用,而不会丢失输入标签: HTML:

        <label class="btn btn-info" radiobuttonlbl>
          <input ng-model="query.gender" type="radio" value="0">male
        </label>

解决方案#1:

.directive("radiobuttonlbl", function() {
  return {
    restrict: 'A',
    link: function(scope, element, attrs, ctrl) {
      element.bind('click', function () {
        var input_elem = angular.element(element.find('input')[0]);
        (function(o, s, v) {
          s = s.replace(/\[(\w+)\]/g, '.$1');
          s = s.replace(/^\./, '');
          var a = s.split('.').reverse();
          while(a.length>1) {
            var k = a.pop();
            o = o[k];
          }
          scope.$apply(function(){ o[a.pop()]=v;});
        })(scope, input_elem.attr('ng-model'), input_elem.attr('value'));
      });
    }
  };
})

解决方案#2:

.directive("radiobuttonlbl", function() {
  return {
    restrict: 'A',
    link: function(scope, element, attrs, ctrl) {
      element.bind('click', function () {
        var input_elem = angular.element(element.find('input')[0]);
        input_elem.prop('checked',true);
        input_elem.triggerHandler('click'); 
      });
    }
  };
})

我感觉第一个更好,因为它使角度做更新工作。

答案 6 :(得分:0)

如果有人仍在寻找一种简便的方法(我个人很犹豫用指令重载我的代码),这就是我所做的:

您可以使用标签上的ng-click来设置值。此外,请注意第一个单选项目标签上的ng-initactive类。这样,您可以让Bootstrap做它的事情,而Angular做它的事情。唯一的缺点是您不能使用ng-model进行角度控制。

<div class="btn-group col-lg-3" data-toggle="buttons">
      <label class="btn btn-default active" ng-init="transaction.debit=true" ng-click="transaction.debit=true">
        <input type="radio" checked> Debit
      </label>
      <label class="btn btn-default" ng-click="transaction.debit=false">
        <input type="radio"> Credit
      </label>
    </div>

答案 7 :(得分:-1)

我遇到同样的问题,在我的情况下,默认样式更改,并且不能在任何收音机或复选框按钮内使用角度ng-model。所以我读了一些文章,发现有时如果你在Bootstrap之后加载JQuery它会覆盖某些内容并且它会阻止默认样式和组件作为引导程序组件加载,如果你在jQuery之后加载angularJS或者反之亦然。

PS.-我的回答:检查您的加载脚本堆栈,使用它并找到适合您的订单。 (第一个jquery,然后是angularJs,最后是bootstrap)。

答案 8 :(得分:-1)

我遇到了同样的问题。使用ng-click标签,它可以正常使用bootstrap

<label class="btn btn-default" ng-click="transaction.debit = 'debit'">

Here it's working in plunker