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

时间:2015-12-13 21:32:29

标签: javascript angularjs

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

在结果中,某些单词是超链接的,因此当您单击它们时,您将获得div中单击的单词的搜索结果。这就像任何在线词典服务功能一样。除了第二个功能似乎在键入搜索后的第一次单击时不起作用,它工作得很好。例如:

您在输入框中输入 pedir ,然后点击查找。下面的div显示了 pedir 的详细含义,包括等超链接字词, pedir 的英文字样。现在,您点击询问,其中应刷新div并显示询问的西班牙语含义,包括 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){});

我甚至不知道我是否可以在小提琴中重现整个情况,因为它涉及一些重要的服务器端脚本。

请告诉我是否有任何我可以解释的信息,以便有人确定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>

2 个答案:

答案 0 :(得分:3)

这:

.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

查看here以获取绑定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中,应用程序内部的所有内容(#)在更改路径时都不会重新加载整个脚本,这是单页应用程序的核心概念:当仅需要更改其中一部分内容时,不会重新加载所有内容。

答案 1 :(得分:3)

最后我开始工作!!有问题的代码在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);。不知道为什么或如何,但这解决了这个问题。