$routeChangeSuccess的奇怪行为:第一次加载时没有触发(但没有抛出任何错误)

Strange behavior of $routeChangeSuccess: Not triggering on first load (but not throwing any error)

本文关键字:错误 任何 routeChangeSuccess 加载 第一次      更新时间:2023-09-26

我甚至不知道如何开始解释这种情况,但我会尽力。我有一个简单的西班牙语-英语-西班牙语词典查找页面,其中有一个文本框、一个lookup按钮和一个显示结果的div。当您在文本框中输入要查找的单词并点击lookup时,结果显示在下面的div中。

在结果中,一些单词是超链接的,所以当你点击它们时,你会在div中得到点击单词的搜索结果。这就像任何在线词典服务功能一样。除了第二个功能在键入搜索后的第一次点击时似乎不起作用之外,它运行得很完美。例如:

在输入框中键入pedir,然后点击Lookup。下面的div现在显示了pedir的详细含义,包括超链接单词,如ask,英语中的佩德尔。现在,单击ask,它将刷新div,并向您显示quest的西班牙语含义,包括pedir等单词。然而,它只是刷新div并显示与第二次查找pedir相同的内容。但是,当您现在再次单击询问时,它会像预期的那样正常工作。必须注意的是,这些单词是适当的超链接,这里没有出现错误链接。不仅如此,其他链接(比如顶部导航选项卡上的链接)在第一次点击时似乎也不起作用。每次查找一个新词时都会发生这种情况。

希望上面的例子能很好地说明问题;至少我已经试过了。我的路由和控制器是这样的:

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

我甚至不知道我是否能轻而易举地再现整个情况,因为它涉及到一些重要的服务器端脚本。

请告诉我是否有什么我可以解释的,以便有人识别破坏我代码功能的小精灵。

p.S.:此问题仅影响执行新搜索后的第一次单击(在页面上的任何链接上),即在输入框中输入一个单词并单击"查找"按钮。

更新:响应@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>

终于开始工作了!!有问题的代码在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);。不知道为什么,也不知道如何解决问题。

这:

.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,使用你的脚本,以棱角分明的方式
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中,当更改路由时,应用程序(#)中的所有内容都不会重新加载整个脚本,这是单页应用程序的核心概念:当只需要更改部分内容时,不会重新加载所有内容。