简体   繁体   中英

Partial View and jQuery graph issues

I've inherited a project and am very green regarding UI. This project uses Bootstrap, nvd3, and flot on Chrome. There is a layout view in which jQuery is referenced, and then partial views for each page are rendered in the layout body. On a dashboard page, the graphs don't show up unless jQuery is again referenced in the scripts, but that reference causes the sidebar to cease working. Referencing easing can be duplicated in the dashboard scripts to get both the graphs to appear and the sidebar to function, but one graph still doesn't work properly. This leads me to believe that jQuery and its libraries are being referenced multiple times on the layout and partial views, wiping out the references that display graphs, activate the sidebar, render graphs correctly, etc.

If that's correct, is there a way to trace each jQuery reference? I've tried deleting multiple references in the source code by sight, moving layout references into the HTML body, testing what's being hit through Chrome Developer Tools, re-calling references as described above as a band-aid, and searching here for similar questions, but nothing seems to achieve both the correct visual and functionality. Also, can a duplicated jQuery reference on a different partial view that shares the same parent layout nullify references in any other partial view? Please opine if there's another possible solution not considered here, because I'm ultimately trying to get the sidebar and graphs working properly. Thanks in advance for looking at this.

Here's the layout with references:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>@ViewBag.Title</title>
    <meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0,user-scalable=no">

    <link rel="shortcut icon" href="/favicon.ico" />

    @Styles.Render("~/Content/css")
    @Styles.Render("~/Content/icons")

    @Scripts.Render("~/bundles/modernizr")

    @RenderSection("headcontent", required: false)

    <!-- page specific stylesheets -->
    <!-- nvd3 charts -->
    <link rel="stylesheet" href="/Content/lib/novus-nvd3/nv.d3.min.css">
    <!-- owl carousel -->
    <link rel="stylesheet" href="/Content/lib/owl-carousel/owl.carousel.css">

    <!-- google webfonts -->
    <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400&amp;subset=latin-ext,latin' rel='stylesheet' type='text/css'>

    <!-- datepicker -->
    <link rel="stylesheet" href="/Content/lib/bootstrap-datepicker/css/datepicker3.css">
    <!-- date range picker -->
    <link rel="stylesheet" href="/Content/lib/bootstrap-daterangepicker/daterangepicker-bs3.css">
    <!-- timepicker -->
    <link rel="stylesheet" href="/Content/lib/bootstrap-timepicker/css/bootstrap-timepicker.min.css">
    <!-- ion.rangeSlider -->
    <link rel="stylesheet" href="/Content/lib/ion.rangeSlider/css/ion.rangeSlider.css">
    <!-- bootstrap switches -->
    <link href="/Content/lib/bootstrap-switch/build/css/bootstrap3/bootstrap-switch.css" rel="stylesheet">
    <!-- 2col multiselect -->
    <link href="/Content/lib/multi-select/css/multi-select.css" rel="stylesheet">
    <!-- multiselect, tagging -->
    <link rel="stylesheet" href="/Content/lib/select2/select2.css">

    <!-- main stylesheet -->
    <link href="/Content/css/style.css" rel="stylesheet" media="screen">

    <!-- moment.js (date library) -->
    <script src="/Content/lib/moment-js/moment.min.js"></script>


    [styles omitted...]

</head>
<body>
    [header omitted...]

    <!-- main content -->
    <div id="main_wrapper">

        [messages omitted...]

        @RenderBody()
    </div>

    <!-- side navigation -->
    <nav id="side_nav">
        @Html.Partial("~/Views/Shared/_SidebarLeft.cshtml")
    </nav>

    <!-- jQuery -->
    <script src="/Content/js/jquery.min.js"></script>
    <!-- easing -->
    <script src="/Content/js/jquery.easing.1.3.min.js"></script>
    <!-- bootstrap js plugins -->
    <script src="/Content/bootstrap/js/bootstrap.min.js"></script>
    <!-- top dropdown navigation -->
    <script src="/Content/js/tinynav.js"></script>
    <!-- perfect scrollbar -->
    <script src="/Content/lib/perfect-scrollbar/min/perfect-scrollbar-0.4.8.with-mousewheel.min.js"></script>

    <!-- common functions -->
    <script src="/Content/js/tisa_common.js"></script>

    @RenderSection("Scripts", required: false)

</body>
</html>

And here's the dashboard HTML:

@using Project.Models
@model DashboardViewModel
@{
    ViewBag.Title = "Home Page";

    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="container-fluid">
    <div class="row">
        <div class="col-md-12">
            <div class="panel panel-default">
                <div class="heading_b">Prices Chart</div>
                <div class="panel-body">
                    <div id="nvd3_cumulativeLine" style="width: 100%; height: 300px">
                        <svg></svg>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Finally, here are the dashboard scripts, with removal of jQuery causing the chart to disappear, removal of easing causing the sidebar to cease pop-outs, and removal of both causing the chart to disappear but leaving sidebar functionality intact.

@section Scripts{
    <!-- page specific plugins -->

    <!-- jQuery DUPLICATE -->
    <script src="/Content/js/jquery.min.js"></script>
    <!-- easing DUPLICATE -->
    <script src="/Content/js/jquery.easing.1.3.min.js"></script>

    <!-- nvd3 charts -->
    <script src="/Content/lib/d3/d3.min.js"></script>
    <script src="/Content/lib/novus-nvd3/nv.d3.min.js"></script>
    <!-- flot charts-->
    <script src="/Content/lib/flot/jquery.flot.min.js"></script>
    <script src="/Content/lib/flot/jquery.flot.pie.min.js"></script>
    <script src="/Content/lib/flot/jquery.flot.resize.min.js"></script>
    <script src="/Content/lib/flot/jquery.flot.tooltip.min.js"></script>
    <!-- clndr -->
    <script src="/Content/lib/underscore-js/underscore-min.js"></script>
    <script src="/Content/lib/CLNDR/src/clndr.js"></script>
    <!-- easy pie chart -->
    <script src="/Content/lib/easy-pie-chart/dist/jquery.easypiechart.min.js"></script>
    <!-- owl carousel -->
    <script src="/Content/lib/owl-carousel/owl.carousel.min.js"></script>

    <!-- dashboard graph functions -->
    <script src="/Content/js/apps/tisa_dashboard.js"></script>

    <script type="text/javascript">
        function cumulativeTestData() {
            var closes = JSON.parse('@Html.Raw(Json.Encode(Model.Coordinates))')
            return [
                {
                    key: "Prices",
                    values: closes
                },
            ];
        }
    </script>
}

You are correct in thinking that there is a conflict when loading the same script multiple times. Only load each script one time.

I can see why trying to remove those scripts from the partial view caused your partial views to fail. You are not loading the scripts until after the partial view. They do not exist until after everything in your partial view has been loaded and executed.

In your layout, move the scripts to the header (preferred) or at least to a point before you pull in the partial view. Then in your partial view, make sure there are no references to scripts which have already been loaded.

In partial views I often use a script wrangler to load in scripts which may or may not have been dynamically loaded. Here is something you can use to attempt to load scripts. It checks to see if a script by the same name has already been loaded on the page (specifically in the header tag) and if it has, it does not attempt to load it again. It's not the prettiest, but it gets the job done.

mycode = function()
{

    //Put all your custom javascript here.
    //This will run when the scripts below have successfully been processed.

}
var headTag = document.getElementsByTagName("head")[0];
var initialScripts = ["/scripts/jquery-2.1.4.min.js",
                        "/scripts/jquery-ui.min.js",
                        "/scripts/jquery.timepicker.min.js"];
var neededScripts = [];
for (var z = 0; z < initialScripts.length; z++) {
    if (!isScriptLoaded(initialScripts[z]))
        neededScripts.push(initialScripts[z]);
}
if(neededScripts.length)
    addScripts(neededScripts, headTag, function () { mycode(); delete mycode; }, 0);
else {
    mycode(); delete mycode;
}
function addScripts(scriptsToLoad, loadTag, callback, i) {
    if (i >= scriptsToLoad.length)
        return;
    var script = scriptsToLoad[i];
    var scriptTag = document.createElement('script');
    scriptTag.setAttribute('type', 'text/javascript');
    scriptTag.setAttribute('src', script);
    if (i >= (scriptsToLoad.length - 1)) {
        scriptTag.onload = callback;
    }
    else {
        scriptTag.onload = function () {
            console.log("Added script file " + script);
            addScripts(scriptsToLoad, loadTag, callback, i + 1);
        }
    }
    loadTag.appendChild(scriptTag);
}

function isScriptLoaded(url) {
    var tags = document.getElementsByTagName('script');
    for (var i = tags.length; i--;) {
        var existingName = tags[i].src.split('/');
        existingName = existingName[existingName.length-1];

        var newName = url.split('/');
        newName = newName[newName.length-1];

        if (existingName == newName) return true;
    }
    return false;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM