Почему пользовательский интерфейс angularJS ломает Bootstrap Formhelper

Я использую Angular JS для многостраничного сайта регистрации. (С этим прекрасным учебником: http://scotch.io/tutorials/javascript/angularjs-multi-step-form-using-ui-router)

Теперь я хочу использовать средство выбора страны Bootstrap Formhelper на одной из страниц ( http://bootstrapformhelpers.com/country/) следующим образом:

<div ui-view>
    ...
    <div class="bfh-selectbox bfh-countries" data-country="AT" data-flags="true"></div>
    ...
</div>

Но это не работает. Сборщик страны не отображается (высота 0).

Если я поставлю сборщик страны за пределы области видимости, то сборщик сработает. Но я хочу, чтобы это было внутри div-интерфейса ui-view:

<div class="bfh-selectbox bfh-countries" data-country="AT" data-flags="true"></div>
<div ui-view>
   ...
</div>

Почему-то директива angularJS ui-view ломает сборщик страны.

Кто-нибудь знает, почему это происходит?

С наилучшими пожеланиями Янник

РЕДАКТИРОВАТЬ:

Мой импорт:

<link rel="stylesheet" href="assets/css/bootstrap.min.css">
<link rel="stylesheet" href="style.css">
<script src="assets/js/angular.js"></script>
<script src="assets/js/angular-animate.js"></script>
<script src="assets/js/angular-ui-router.min.js"></script>
<script src="assets/js/angular-animate.js"></script>
<script src="app.js"></script>
<!-- Bootstrap -->
<script src="assets/js/jquery-1.11.1.min.js"></script>
<link rel="stylesheet" href="assets/css/bootstrap-theme.min.css">
<script src="assets/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="assets/css/bootstrap-formhelpers.min.css">
<script src="assets/js/bootstrap-formhelpers.min.js"></script>
<script src="assets/js/bootstrap-formhelpers-states.js"></script>
<script src="assets/js/bootstrap-formhelpers-countries.de-DE.js"></script>
<script src="assets/js/bootstrap-formhelpers-countries.js"></script>

EDIT2:

теперь я использую директиву для инициализации. странно думать, что этот код работает:

angular.module("formApp").directive('nationpicker', function ($parse) {
return {
    restrict: 'A',
    replace: false,
    transclude: false,
    link: function (scope, element, attrs) {
        element.append('<select id="countries1" class="form-control"></select>');
        $('#countries1').bfhcountries({flags:true})
    }
};

Но этот код не работает:

angular.module("formApp").directive('nationpicker', function ($parse) {
return {
    restrict: 'A',
    replace: false,
    transclude: false,
    link: function (scope, element, attrs) {
        element.append('<div id="country" class="bfh-selectbox bfh-countries" data-country="AT" data-flags="true"></div>');
        $('#country').bfhcountries({flags:true})
    }
};

На самом деле это только разные примеры из Bootstrap Formhelper (см. Ссылку вверху)

первый пример 3. второй код, который не работает, взят из моего предпочтительного примера 4. Пример.

Может кто-нибудь сказать, пожалуйста, почему это не работает для 4. Пример?

2 ответа

Решение

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

Проблема не в директиве ui-view, а в директиве сборщика. Вот обновленный код директивы:

angular.module("formApp").directive('nationpicker', function ($parse) {

    // The directive has been rewritten to work properly
    return {
        restrict: 'A', // It is an attribute
        require: '?ngModel', // It uses ng-model binding
        scope: {
          ngModel: '='
        },
        link: function (scope, elem, attrs, ctrl) {
            // Add the required classes
            elem.addClass('bfh-countries');
            elem.addClass('bfh-selectbox');

            // First we initialize the selectbox with the desired options
            elem.bfhselectbox({
                filter: (elem.attr('data-filter') == 'true') ? true : false
            }).on('change.bfhselectbox', function() {
                // Listen for the change event and update the bound model
                return scope.$apply(function () {
                    return scope.ngModel = elem.val();
                });
            });

            // Initialize the countries with the desired options
            return elem.bfhcountries({
                flags: (elem.attr('data-flags') == 'true') ? true : false,
                country: scope.ngModel || 'AT'
            });
        }
    };
});

Чтобы это работало, нужно было внести пару изменений в ваш элемент в HTML

<div nationpicker id="country" data-flags="true" data-filter="true" ng-model="nation"></div>

Обратите внимание, что классы больше не включены. Это обрабатывается директивой сейчас. Я также решил связать страну в области действия контроллера, а не использовать атрибут data-country. Это было так просто, как добавление $scope.nation = 'AT'; в контроллере.

Мне также пришлось переместить все ваши угловые теги сценариев ниже сценариев начальной загрузки и помощника по формам.

<!-- Bootstrap -->
<script src="assets/js/jquery-1.11.1.min.js"></script>
<link rel="stylesheet" href="assets/css/bootstrap-theme.min.css">
<script src="assets/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="assets/css/bootstrap-formhelpers.min.css">
<script src="assets/js/bootstrap-formhelpers.min.js"></script>
<script src="assets/js/bootstrap-formhelpers-states.js"></script>
<script src="assets/js/bootstrap-formhelpers-countries.de-DE.js"></script>
<!--<script src="assets/js/bootstrap-formhelpers-countries.js"></script>-->


<!-- moved all angular related scripts to here -->
<script src="assets/js/angular.js"></script>
<script src="assets/js/angular-animate.js"></script>
<script src="assets/js/angular-ui-router.min.js"></script>
<script src="assets/js/angular-animate.js"></script>
<script src="app.js"></script>
<script src="directive.js"></script>

Я также свяжусь с вами по электронной почте и надеюсь, что это поможет вам продолжить ваш проект.

Для работы двустороннего связывания вы можете изменить код директивы, как показано ниже:

myApp.directive('nationpicker', function ($parse) {
    return {
        restrict: 'A', // It is an attribute
        require: '?ngModel', // It uses ng-model binding
        scope: {
            ngModel: '='
        },
        link: function (scope, elem, attrs, ctrl) {
            // Add the required classes
            elem.addClass('bfh-countries');
            elem.addClass('bfh-selectbox');
            // First we initialize the selectbox with the desired options
            elem.bfhselectbox({
                filter: (elem.attr('data-filter') == 'true') ? true : false
            }).on('change.bfhselectbox', function () {
                // Listen for the change event and update the bound model
                return scope.$apply(function () {
                    return scope.ngModel = elem.val();
                });
            });
            scope.$watch('ngModel', function (newVal, oldVal) {
                if (newVal != oldVal) {
                    elem.find("input").val(newVal);
                    elem.find("span.bfh-selectbox-option").empty().append('<i class="glyphicon bfh-flag-' + newVal + '"></i>' + BFHCountriesList[newVal]);
                }
            });


            // Initialize the countries with the desired options
            return elem.bfhcountries({
                flags: (elem.attr('data-flags') == 'true') ? true : false,
                country: scope.ngModel
            });
        }
    };
});
Другие вопросы по тегам