AngularJS: Радио кнопки не работают с Bootstrap 3

У меня есть переключатель, который устанавливает значение True или False на основе значения типа транзакции

Демо можно найти здесь

Проблема заключается в том, что когда я нажимаю на любой из переключателей, значение $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-UI или AngularStrap для этой цели, если не доступен другой вариант.

Ответы

Ответ 1

У вас есть большая надпись, прикрепленная к верхней части радиокнопки, которая предотвращает ввод ваших переключателей. 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>

Затем он работает, конечно, он может не выглядеть так, как вы этого хотите.

Ответ 2

Я изменил решение dpineda. Вы можете использовать, не удаляя зависимость bootsrap.js. Также есть рабочий пример здесь.

Это поток:

  • Удалите data-toggle="buttons" для предотвращения выполнения начальной загрузки.
  • Добавить CSS для исправления разбитого представления (класс btn-radio css)
  • Добавьте некоторую логику AngularJS для отмеченного эффекта стиля.

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;
}

Ответ 3

Я нашел проблему в 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))
})

Ответ 4

если вы удалите код начальной загрузки, вы можете управлять стилями с помощью условных выражений

<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>

Ответ 5

Здесь рабочая версия с использованием новой директивы:

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;
          });
        }
      });
    }
  };
})

Ответ 6

Основываясь на ответе 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'); 
      });
    }
  };
})

У меня есть ощущение, что первое лучше, потому что он делает angular работу по обновлению.

Ответ 7

У меня такая же проблема, в моем случае, изменение стиля по умолчанию и не может использовать angular ng-model внутри любой радиостанции или кнопки флажка. Поэтому я прочитал несколько статей и обнаружил, что иногда, если вы загружаете JQuery после Bootstrap, он перезаписывает что-то и предотвращает загрузку стилей и компонентов по умолчанию в качестве компонентов начальной загрузки, это также происходит, если вы загружаете angularJS после jQuery или наоборот.

PS.- Мой ответ: проверьте свой стек script, поиграйте с ним и найдите, какой заказ работает для вас. (первый jquery, затем angularJs, наконец, бутстрап).

Ответ 8

У меня была та же проблема. Используйте ng-click на ваших ярлыках, и он отлично справится с загрузкой

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

Здесь он работает в plunker