2013-10-03 4 views
15

У меня есть переключатель, который устанавливает значение True или False на основе значения типа сделкиAngularJS: Радио кнопки не работают с Bootstrap 3

Демо можно найти 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-UI или AngularStrap для этой цели, если нет другого варианта.

+0

Вы правы. Удаление кода бутстрапа вокруг ваших переключателей заставляет их работать снова. Я подозреваю, что радиокнопки на самом деле не выбраны из-за бутстрапа? Обратите внимание, что удаление ссылки на скрипт для файла bootstrap.js также заставляет их работать снова, даже при работе css –

+0

. Вы также можете найти аналогичную проблему ([Угловая ремешка не будет обновлять модель] (http: // stackoverflow .com/д/23613450/1977012)). Хотя это касается столкновения библиотек, и в основном это относится к 'bootstrap3' +' угловому ремню', но кто-то (или вы в будущем) можете его искать. – Egel

ответ

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

Удаление файла bootstrap.js устраняет проблему, которая заставляет меня думать, что это не имеет никакого отношения к ярлыкам, но больше всего подходит для загрузки javascript для загрузки. Между тем, удаление ярлыков, конечно же, прекращает работу javascript bootstrap на этих объектах. –

+6

Альтернативой является обработка щелчка и взаимодействие данных с помощью ng-click на ярлыках. Тогда вам не нужно будет удалять javascript. http://plnkr.co/edit/8i86U2?p=preview – user2789093

+0

В этой ссылке объясняется, как использовать Bootstrap и Angular: https://scotch.io/tutorials/how-to-correctly-use-bootstrapjs-and-angularjs- вместе – Chocksmith

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

Директива слишком специфична. Потеряла функциональность бутстрапа с вашим решением. '.debit = undefined' ничего не делает. -1 – A1rPun

2

если вы удалите де код начальной загрузки вы можете контролировать стили с условными

<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

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

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

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

+0

Идеально. Это была проблема. Я загрузил свой bootstrap.min.js до jquery.min.js, и проблема полностью исчезла! Спасибо. – Nabeel

+1

Unfortnatelly, это решило эту конкретную проблему, но сломало все остальное, поскольку jQuery является зависимостью от Bootstrap – Nabeel

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

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

+0

Этот ответ не идеален, но самый лучший на этой странице. – A1rPun

9

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

Это поток:

  1. Удалить data-toggle="buttons" для предотвращения самозагрузки выполнения.
  2. Добавить CSS для исправления разбитого представления (класс btn-radio css)
  3. Добавьте некоторую логику 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; 
} 
+0

Я обнаружил, что ключевой проблемой было удаление кнопок «data-toggle =» «', чтобы отключить этот бит функции bootstrap.js, а затем добавить вышеприведенный стиль, чтобы компенсировать повторное появление реальных переключателей. –

-1

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

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

Here it's working in plunker

Смежные вопросы