Содержимое Codemirror не отображается в bootstrap modal, пока не будет нажато

Я использую codemirror 3 с бутстрапом. В моем bootstrap modal есть текстовое поле, и я заменяю его на codemirror. Я использую task_name_editor.setValue('initial value') для инициализации codemirror с помощью ввода. Проблема в том, что содержимое есть, но оно не отображается до тех пор, пока оно не будет нажато, или любая клавиша не будет нажата во время фокусировки.

Я попробовал Marijn ответить на аналогичный вопрос, но я не знаю, где разместить task_name_editor.refresh()

Я попытался разместить его, где я покажу модальный -

$('#edit_task_modal').modal('show');
task_name_editor.setValue('initial value');
task_name_editor.refresh();

даже тогда он не работает Пожалуйста, может кто-нибудь показать, как исправить эту проблему?

Ответ 1

Возможно ли более чистое решение?

Модификации Bootstrap имеют событие, которое срабатывает после отображения модальности. В Bootstrap 3 это shown.bs.modal.

modal.on('shown.bs.modal', function() {
    // initialize codemirror here
});

Ответ 2

С помощью этого вопроса мне удалось получить редактор CodeMirror, который сидел в неактивной загрузочной вкладке 3 и, следовательно, не полностью инициализировался и обновил ее при нажатии на вкладку. Может быть, кто-то сочтет это полезным.

Версия coffeescript:

$('a[data-toggle="tab"]').on 'shown.bs.tab', (e) ->
  target = $(e.target).attr("href") # activated tab
  $(target + ' .CodeMirror').each (i, el) ->
    el.CodeMirror.refresh()

Ответ 3

Если вы инициализируете редактор в модальном показанном событии, проблема будет решена. Просто поставьте этот script на родительскую страницу.

$('#myModal').on('shown', function () {
    CodeMirror.fromTextArea(document.getElementById('MyTextArea'), { mode: 'xml', lineNumbers: true });
});

Ответ 4

Я полагал, что это связано с изменением размера видового экрана, в то время как вкладки скрыты и снова отображаются. Поэтому для меня работало следующее:

1) Прослушивание кликов по вкладкам 2) При щелчке, обновите вызов() во всех редакторах CM или только внутри вкладки, как вы предпочитаете

Важно отметить, что refresh() необходимо вызывать с небольшим тайм-аутом, иначе в некоторых браузерах (я получил это в Chrome) редактор отображается, но с некоторыми недопустимыми смещениями.

Попробуйте что-то вроде этого:

$(document).ready(function() {
    $("#your_nav_tabs a").click(function(e) {
        if(window.codeMirrorInstances != null) { // window.codeMirrorInstances must be initialized and tracked manually
            $.each(window.codeMirrorInstances, function(index, cm) {
                setTimeout(function() {
                    cm.refresh();
                }, 100);
            });
        }

        return false;
    });
});

Ответ 6

У меня есть аналогичная проблема с загрузкой в ​​целом (не специально с модалами). Тем не менее, мое решение состояло в том, чтобы убедиться, что я создал редактор codemirror как можно раньше (а не в событии, готовящемся к документу). Я предполагаю, что это имеет какое-то отношение к тому, как bootstrap вычисляет ширины и высоты в сетке.

<body>
    <!-- my page content -->

    <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>

    <script type="text/javascript">
        // Create the code editor here rather than on document.ready
        editor = CodeMirror(...);
    </script>
</body>

Ответ 7

У меня была очень похожая проблема с CodeMirror: если она была инициализирована, пока она не была активной вкладкой начальной загрузки, она не показывала никакого содержимого. Мое обходное решение было противоположным от @pbergqvist - для инициализации элемента управления CodeMirror как можно позже, т.е. После выбора выбранной вкладки. Используя TypeScript, он выглядит примерно так:

var tabClicked = $.Deferred();
$('#scriptTab').click(() => tabClicked.resolve());
$.ajax('/api/script')
    .done(script => {
        this.tabClicked.done(() => {
            setTimeout(()=> {
                var codeMirror = CodeMirror.fromTextArea($('#script')[0]);
                codeMirror.getDoc().setValue(script);
            }, 10);
        });
    })
    .fail(err=> console.error('Error retrieving script: ' + JSON.stringify(err)));

Надеюсь, это поможет кому-то.

Ответ 8

(angular, самозагрузка) Я просто решил это с простым таймаутом, например:

<button class="btn btn-default pull-right margin" data-toggle="modal" data-target="#codesnippetmodal" ng-click="getcodesnippet(module)">
 open modal
</button>

а затем в моем контроллере:

$scope.getcodesnippet = function(module) {
    var clientmodule = {
        clientid: $rootScope.activeclient.id,
        moduleid: module.id
    }
    Data.post('getCodesnippet', {
        clientmodule: clientmodule
    }).then(function(results) {

        codesnippet_editor.setValue(results.codesnippet);
        setTimeout(function() {
            codesnippet_editor.refresh();
        }, 500);
    });
}

Ответ 9

чтобы не обновляться каждый раз (это означает, что позиция и потеря потеряны). Я настоятельно рекомендую использовать следующее:

$('#meinetabs a[data-toggle="tab"]').on('shown.bs.tab', function (e) 
{
    if (var5 !=="5")
         {
            editor_htaccess.refresh();
         }
    var5 = "5";
})  

Его под лицензией MIT, потому что я такой приятный человек