2015-09-17 5 views
2

Я пытаюсь вставить HTML-код для переключателя Bootstrap Switch (http://www.bootstrap-switch.org/) с контроллера AngularJS, используя ngBind. Переключатели Bootstrap Switch, которые уже работают в HTML, когда я запускаюAngularJS - ngBind и Bootstrap Switch

$ ('. Bs-switch'). BootstrapSwitch();

Но переключатель, который я вставляю в HTML через ngBind, остается простым переключателем. Я думаю, что это вопрос времени.

Пример:

HTML:

<!-- this doesn't get converted to a Bootstrap Switch radio button --> 
<div ng-bind-html="exampleHTML"></div> 

<!-- this does get converted --> 
<input type="checkbox" class="bs-switch" name="my-checkbox2" checked> 

Контроллер:

$scope.exampleHTML = $sce.trustAsHtml(
     '<input type="checkbox" class="bs-switch" ' + 
     '  name="my-checkbox1" checked>' 
); 

$('.bs-switch').bootstrapSwitch(); 

Если я что-то вроде следующего в контроллере, радио-кнопка вставляется через ngBind получает преобразован в коммутатор Bootstrap - вот почему я думаю, что это проблема синхронизации:

$scope.exampleHTML = $sce.trustAsHtml(
    '<input type="checkbox" class="bs-switch" ' + 
    '  name="my-checkbox1" checked>' 
); 

setTimeout(function() { 
    $('.bs-switch').bootstrapSwitch(); 
}, 1000); 

Любое предложение о том, как это сделать (лучше, чем использовать таймаут)? Я пытаюсь создать динамическую форму, которая создается программно из конфигурационного файла JSON, поэтому я использую ngBind для вставки HTML.

UPDATE:

Вот JSFiddle example

+2

Почему вы должны вставить HTML, что путь? Мантра для Angular не должна манипулировать DOM от контроллеров. – BjornJohnson

+0

можете ли вы разместить plunkr или что-то ?, но я предполагаю, что вы хотите уловить флажок check check или изменить, а затем скрыть флажок и показать директиву bs-switch? –

+0

BjornJohnson - причина, по которой я делаю это, - это то, что я хочу динамически создавать формы из данных JSON. Сказав это, я не вижу другого способа сделать это - не так ли? – Bill

ответ

2

Не манипулировать DOM внутри контроллера, используйте директиву вместо:

<div ng-app="myApp"> 
    <div ng-controller="myController"> 
     <switch></switch> 
    </div> 
</div> 

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

myApp.controller('myController', ['$scope', 
    function($scope) { 

    } 
]).directive('switch', function() { 
    return { 
     restrict: 'E', 
     'template': '<input type="checkbox" class="bs-switch" name="my-checkbox1" checked>', 
     'link': function(scope, element, attrs) { 
      $(element).find('input').bootstrapSwitch(); 
     } 
    } 
}); 

Fiddle https://jsfiddle.net/nnkypoy9/23/

2

ОК, это, кажется, работает:

'use strict'; 

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

myApp.controller('myController', ['$scope', '$sce', 
    function($scope, $sce) { 

     // from https://stackoverflow.com/questions/29093229/how-to-call-function-when-angular-watch-cycle-or-digest-cycle-is-completed 
     var hasRegistered = false; 
     $scope.$watch(function() { 
      if (hasRegistered) return; 
      hasRegistered = true; 
      $scope.$$postDigest(function() { 
       hasRegistered = false; 
       $('.bs-switch').bootstrapSwitch(); 
      }); 
     }); 

     $scope.exampleHTML = $sce.trustAsHtml(
      '<input type="checkbox" class="bs-switch" ' + 
      '  name="my-checkbox2" checked>' 
     ); 

    } 
]); 

https://jsfiddle.net/billb123/nnkypoy9/19/

Это основано на следующем переполнением стека вопрос:

how to call function when angular watch cycle or digest cycle is completed

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