Подтвердить что ты не робот

Странное поведение $routeChangeSuccess: не запускается при первой загрузке (но не выбрасывается какая-либо ошибка)

Я понятия не имею, как даже начать объяснять эту ситуацию, но я постараюсь изо всех сил. У меня есть простая страница поиска испанского и англо-испанского словарей с текстовым полем, клавишей Поиск и div, чтобы показать результаты. Когда вы вводите слово для поиска в текстовое поле и нажимаете Поиск, результаты отображаются в разделе ниже.

В результате некоторые слова гиперссылки, поэтому, когда вы нажимаете на них, вы получаете результат поиска для щелкнутого слова в div. Это точно так же, как и любые функции онлайн-словаря. Он отлично работает, за исключением того, что вторая функциональность не работает при первом нажатии после типизированного поиска. Например:

В поле ввода введите pedir и нажмите Поиск. Ниже приведенный ниже div показывает подробное значение pedir, включая гиперссылки, такие как ask, английский для pedir. Теперь вы нажимаете спрашивать, который должен обновить div и показать вам значения из ask, включая слова типа pedir. Однако он просто обновляет div и показывает тот же контент, что и второй раз. Но когда вы нажмете спросить второй раз, он отлично работает, как и ожидалось. Следует отметить, что слова гиперссылки соответствующим образом, и здесь нет неправильной связи. Кроме того, другие ссылки (например, те, что находятся на вкладке навигации сверху) также не работают при первом нажатии. Это происходит каждый раз, когда новое слово просматривается.

Надеемся, что приведенный выше пример достаточно хорошо иллюстрирует проблему; по крайней мере, то, что я пробовал. Мои маршрутизаторы и контроллеры выглядят следующим образом:

var asApp = angular.module('asApp', ['ngRoute']);
asApp.config(function($routeProvider) {
    $routeProvider
.when('/', {
            title: 'Home of thesite – Radical Spanish learning tips and tricks for the adventurous learner',
            templateUrl : 'pages/home.html',
            controller  : 'mainController'
        })
// route for dictionary
        .when('/dictionary', {
            title: 'The dictionary',
            templateUrl : 'pages/dictionary.html',
            controller  : 'mainController'
        })

        // route for dictionary term
        .when('/dictionary/:word2lookup', {
            title: 'The thesite dictionary',
            templateUrl : 'pages/dictionary.html',
            controller  : 'dictController'
        })

        // route otherwise
        .otherwise({
            title: 'thesite – Radical Spanish learning tips and tricks for the adventurous learner',
            templateUrl : 'pages/home.html',
            controller  : 'mainController'
        });

});

function HeaderController($scope, $location) 
{ 
    $scope.isActive = function (viewLocation) { 
        return viewLocation === $location.path();
    };
}

asApp.run(['$rootScope', '$route', '$location', function($rootScope, $route, $location) {
$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
    document.title = 'Translation of ' + $route.current.params['word2lookup'] + ' | ' + $route.current.title;
});
}]);

asApp.controller('mainController', function($scope) {});
asApp.controller('dictController', function($scope, $routeParams){});

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

Пожалуйста, дайте мне знать, если что-нибудь, что я мог бы объяснить, чтобы кто-то определил, что gremlin нарушает мои функциональные возможности кода.

PS. Эта проблема влияет только на первый клик (по любой ссылке на странице) после того, как был выполнен новый поиск, т.е. в поле ввода вводится слово и нажата кнопка поиска.

Обновление. В ответ на запрос @gr3g, здесь код для функций lookup_check() и lookup_word():

function lookup_check(lookupterm){
    close_kb();
    if(lookupterm != ""){
        lookup_word(lookupterm);
    }
    else{
        var lookup_box = $('#word');
        lookup_box.addClass('empty');
        setTimeout(function(){ lookup_box.removeClass('empty'); },500);
    }
}
// Query dictionary and populate meaning div
function lookup_word(lookupword){
    var mean = document.getElementById('meaning');
    var waittext = '<div class="preloader-image"><br /><br />';
    var hr = createXMLHTTPRequestObject();
    var url = 'bootstrap/php/dictengine.php';
    var vars = "lookup_word=" + lookupword;
    document.getElementById('word').value = lookupword;
    hr.open("POST", url, true);
    hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    hr.onreadystatechange = function(){
        if(hr.readyState == 4 && hr.status == 200){
            var return_data = hr.responseText;
            mean.innerHTML = return_data;
            if ($(".el")[0]){ hist_mean = $('.el:first').text(); }
            else { hist_mean = ""; }
            add2local(lookupword, hist_mean);
            $(".tab-container").addClass("hide-tabs");
            if($("#dict_span").length != 0) {
                $(".tab-container").removeClass("hide-tabs");
                // logic to seggregate spanish and english results
                $("#dict_eng").addClass("hide-div");
                $("#sp_tab").addClass("active");
                $("#en_tab").removeClass("active");
            }
            document.title = 'Translation of ' + lookupword + ' | The thesite dictionary';
            $("<hr class='dict-divider'>").insertAfter(".gram_cat");
            $("<hr class='dict-divider'>").insertAfter(".quickdef");
            $("<hr class='dict-divider'>").insertBefore(".dict_source");
            $('div.entry_pos').wrap('<div class="pos"></div>');
            $('a.dictionary-neodict-first-part-of-speech').wrap('<div class="pos"></div>');
            // update url
            var loc = window.location.href;
            var lastpart = loc.substring(loc.lastIndexOf('/') + 1);
            if(lastpart == 'dictionary'){ window.location.replace(window.location.href + "/" + encodeURI(lookupword)); }
            if((lastpart != 'dictionary') && (lastpart != encodeURI(lookupword))){
                var addr = window.location.href;
                var addrtemp = addr.substring(addr.lastIndexOf('/') + 1);
                addr = addr.replace(addrtemp, encodeURI(lookupword));
                if(!!(window.history && history.pushState)){ history.pushState(null, null, addr); }
                else{ window.location.replace(addr); }
            }
        }
        //else { setTimeout('lookup_word(lookupword)', 1000); }
    }
    hr.send(vars);
    mean.innerHTML = waittext;
}

Обновление 2. Для дальнейшего облегчения @gr3g, здесь dictionary.html:

<!-- dictionary.html -->
<script>
    var loc = window.location.href;
    var lastpart = loc.substring(loc.lastIndexOf('/') + 1);
    if(lastpart != 'dictionary'){ lookup_check(decodeURI(lastpart)); }

    // populate search history if available
    var recent = document.getElementById('recent-lookups');
    var value = localStorage.getItem('w');
    if (value) {
        value = JSON.parse(value);
        var len = value.length - 1;
        var str = "";
        for (a=len; a>=0; a--){
            term = value[a].substr(0, value[a].indexOf('$'));
            term_meaning = value[a].substr(value[a].indexOf("$") + 1);
            if(term_meaning != "") {
            str = str + "<p><strong><a href='/a-s/#/dictionary/" + encodeURI(term) + "'>" + term + "</a></strong>&nbsp;&nbsp;<i class='fa fa-chevron-right' style='color: #a5a5a5;font-size: 80%;'></i>&nbsp;&nbsp;<span class='recent_meanings'>" + term_meaning + "</span></p>";
        }
            else { str = str + "<p><em>" + term + "</em></p>"; }
        }
        recent.innerHTML = str;
    }
    else { recent.innerHTML = "<p>No historical data to show right now. Words will start appearing here as you begin your lookups.</p>"; }

    // populate word of the day on pageload
    wotd();

</script>

<!-- top-image start -->
<div class="page-header-line-div">
</div>
<!-- top-image end -->
<br>
<br>

<div class="container-fluid" ng-controller="luController as luCtrl">
    <div class="row row-padding">
        <form class="form-horizontal" role="form" name="lookup-form" id="lookup-form" action="" method="">
            <div class="input-group col-md-6">
                <input  id="word" type="textbox" placeholder="Enter a Spanish or English word here..." class="form-control input-lg lookup-field lookup-field-single" onMouseOver="$(this).focus();" required ng-model="luCtrl.lookuptrm">
                <i class="fa fa-times fa-lg delete-icon" onfocus="clearword();" onclick="clearword();" data-toggle="tooltip" data-placement="top" title="Click to clear entered text"></i>
              <i class="fa fa-keyboard-o fa-2x kb-icon" onfocus="toggler('virtualkeypad', this);" onclick="toggler('virtualkeypad', this);" data-toggle="tooltip" data-placement="top" title="Click to enter accented characters"></i>
                <div class="input-group-btn">
                    <button class="btn btn-lg btn-primary lookup-submit" type="submit" id="lookup" ng-click="luCtrl.handlelookup(luCtrl.lookuptrm)">Lookup</button>
                </div>
            </div>
            <div id="virtualkeypad" class="btn-group vkb-hide"><!--col-md-offset-4-->
              <button class="btn btn-lg first-btn" type="button" onClick="spl_character('á');">á</button>
              <button class="btn btn-lg" type="button" onClick="spl_character('é');">é</button>
              <button class="btn btn-lg" type="button" onClick="spl_character('í');">í</button>
              <button class="btn btn-lg" type="button" onClick="spl_character('ó');">ó</button>
              <button class="btn btn-lg" type="button" onClick="spl_character('ú');">ú</button>
              <button class="btn btn-lg" type="button" onClick="spl_character('ü');">ü</button>
              <button class="btn btn-lg last-btn" type="button" onClick="spl_character('ñ');">ñ</button>
            </div>
        </form>

        <!-- tabbed view for bilingual words -->
        <div class="col col-md-8 bi">
            <ul class="nav nav-tabs tab-container hide-tabs lang-tabs" role="tablist">
                <li class="nav active" id="sp_tab" onClick="$(this).addClass('active'); $('#en_tab').removeClass('active'); $('#dict_eng').addClass('hide-div'); $('#dict_span').removeClass('hide-div');"><a href="" data-toggle="tab">Spanish</a></li>
                <li class="nav" id="en_tab" onClick="$(this).addClass('active'); $('#sp_tab').removeClass('active'); $('#dict_span').addClass('hide-div'); $('#dict_eng').removeClass('hide-div');"><a href="" data-toggle="tab">English</a></li>
            </ul>
            <div class="dictionary-result" id="meaning">
                <p class="box-text">This bilingual dictionary is an actively growing resource accumulating new words each day. Currently drawing from the best names in the world of Spanish/English dictionary, such as <strong>Collins</strong><sup>®</sup> and <strong>Harrap</strong><sup>®</sup>, it continues to improve with every lookup you perform. It includes regionalism, colloquialism, and other non-standard quirkiness from over a dozen Spanish dialects ranging from Peninsular to Mexican and Argentinean to Cuban. This dictionary also includes a growing number of specialty terms specific to niches such as medicine, economics, politics, etc.</p>
                <p class="box-text">Please use this page only for dictionary lookups and not comprehensive translations. You can enter either English or Spanish terms and the dictionary will automatically guess the language it belongs to. Keep your inputs to within 20 characters (that should be long enough to handle any English or Spanish word you might want to look up).</p>
            </div>
        </div>



        <!-- sidebar -->
        <div class="col col-md-4">
            <!-- history panel -->
            <div class="panel panel-default panel-box card-effect">
              <div class="panel-heading panel-title">Recent Lookups</div>
              <div id="recent-lookups" class="panel-body panel-text">
                No historical data to show right now. Words will start appearing here as you begin your lookups.
              </div>
            </div>
            <!-- WOTD panel -->
            <div class="panel panel-default panel-box card-effect">
              <div class="panel-heading panel-title">Word of the Day</div>
              <div id="wotd" class="panel-body panel-text">
                Word of the day not currently available.
              </div>
            </div>
        </div>
    </div>
</div>
4b9b3361

Ответ 1

Наконец, я получил его на работу! Код нарушения был в lookup_word():

if(!!(window.history && history.pushState)){ history.pushState(null, null, addr); }
                else{ window.location.replace(addr); }

Я просто удалил блок if и заменил его на history.pushState(null, null, addr); window.location.replace(addr);. Не знаю, почему и как, но это разрешило проблему.

Ответ 2

Это:

.otherwise({
            title: 'TheSite – Radical Spanish learning tips and tricks for the adventurous learner',
            templateUrl : 'pages/home.html',
            controller  : 'mainController'
        });

Можно заменить на это:

.otherwise("/");

В вашем HTML:
Этого следует избегать:

onclick="$('#word').blur(); lookup_check($('#word').val());"

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

onclick="$('#word').blur(); lookup_check(variableValueBindToInput)"

Вы можете показать функцию lookup_check? А также показать, как вы вызываете функцию look_up из ссылки?

Вот Plunker, используя ваши скрипты, в angular.
http://plnkr.co/edit/EP8y7DrTmzr0WdRkQSew?p=preview

Посмотрите здесь для привязки html.

Есть ли

    var loc = window.location.href;
    var lastpart = loc.substring(loc.lastIndexOf('/') + 1);
    if(lastpart != 'dictionary'){ lookup_check(decodeURI(lastpart)); }

Делает запрос XHR на загрузку страницы при щелчке ссылки (которая задает слова запроса в URL-адресе)?

Если это так, вы не можете использовать:

str = str + "<a ng-click='lookup_checkFromLink(request)'>";

И не проверяйте загрузку страницы?
Потому что в AngularJs все, что находится внутри приложения (#), не перезагружает весь script при смене маршрута, что является основной концепцией приложений одиночной страницы: не перезагружать весь контент, когда нужно изменить только его часть.