2017-10-03 16 views
11

Tôi đã sử dụng ScriptManager và tiện ích con trượt jQuery cùng nhau trên các trang web trong nhiều năm, nhưng gần đây tôi đã nảy ra một vấn đề khiến tiện ích không hoạt động. Tôi đã xoay sở để giải quyết vấn đề, nhưng nó không may mắn hơn là chuyên môn. Tôi hy vọng rằng ai đó có thể cung cấp lý do đằng sau vấn đề và rằng bản sửa lỗi có thể hữu ích cho những người khác có cùng vấn đề.Asp.Net ScriptManager gây ra sự cố với jQuery Widget

tôi sử dụng một aggregator kịch bản trong đó kết hợp các kịch bản của tôi với nhau - đây là những gì nó chứa - tất cả các đoạn mã đã được ghép nối xuống cho ngắn gọn:

vendor/Modernizr.min.js 
vendor/jQuery.3.0.0.min.js 
vendor/jQuery-UI.1.12.1.min.js 
vendor/jQuery-UI.TouchPunch.min.js 
propriertary/LoanSelector.js 
DefaultInit.js 

Dưới đây là nội dung của DefaultInit.js:

$(document).ready(function() { 
    loanSelector.init(); 
}); 

Dưới đây là xương trần của LoanSelector.js

var loanSelector = function() { 

    var pub = {}, $ctl = $("#loan-selector"), 
     $sliderAmount = $ctl.find(".slider-amount:first"), 
     $widgetAmount = $sliderAmount.find(".widget:first"); 

    function initControl() { 
     initWidgetAmount(100, 2000, 100, $("#hfStartAmount").val()); 
    } 

    function initWidgetAmount(min, max, step, initialVal) { 
     $widgetAmount.slider({ 
     }); 
    } 

    pub.init = function() { 
     initControl(); 
    }; 

    return pub; 
}(); 

Bây giờ này hoạt động - nhưng chỉ không có ScriptManager trên trang.

Khi trình quản lý tập lệnh được thêm vào, tiện ích con trượt không tải - không có lỗi - không có gì.

Các yếu tố được lưu trong bộ nhớ cache là đồ đạc cố định trên trang - do đó, nó không phải là trường hợp các yếu tố không tồn tại tại một thời điểm.

Dưới đây là đoạn code ScriptManager:

<asp:ScriptManager ID="SM" runat="server" 
     EnableCdn="true" 
     LoadScriptsBeforeUI="false" 
     EnablePageMethods="true"> 
    </asp:ScriptManager> 

Nếu tôi thực hiện thay đổi, tôi có thể nhận được các widget để tải với ScriptManager trên trang - đây là một phiên bản khác của LoanSelector.js rằng hoạt động:

var loanSelector = function() { 

    var pub = {}, $ctl, $sliderAmount, $widgetAmount; 

    function cacheElements() { 
     $ctl = $("#loan-selector"), 
     $sliderAmount = $ctl.find(".slider-amount:first"), 
     $widgetAmount = $sliderAmount.find(".widget:first"); 
    } 

    function initControl() { 
     // This is new 
     cacheElements(); 

     initWidgetAmount(100, 2000, 100, $("#hfStartAmount").val()); 
    } 

    function initWidgetAmount(min, max, step, initialVal) { 
     $widgetAmount.slider({ 
     }); 
    } 

    pub.init = function() { 
     initControl(); 
    }; 

    return pub; 
}(); 

Vì vậy, bất cứ ai có thể ném một số ánh sáng về lý do tại sao nó có thể không hoạt động và tại sao sửa chữa không hoạt động?

+0

một vài câu hỏi, là có bất kỳ sai sót trong giao diện điều khiển? bạn đã thử đặt trình gỡ rối chưa; vào các phần chức năng của bạn để xem những gì là hit? hàm init() của loanSelector là gì? Tôi thấy nó trên đối tượng pub, nhưng bạn đang gọi vaySelector.init(), bạn chỉ cần gọi loanSelector()? – andrewf

+0

Tôi nghĩ có thể ScriptManager phải thay đổi cách các tập lệnh được tải, nếu kịch bản của bạn tải trước khi HTML được tải, thì nó không thể tìm thấy phần tử. Cách dễ nhất để kiểm tra điều này là thêm "conslole.log ($ ctl.length) cho mỗi giải pháp làm việc và không làm việc ngay trước khi gọi phương thức initWidgetAmount. Nếu độ dài là 0, trong mẫu không hoạt động, cho biết nội dung HTML không được tải khi phương thức được gọi là –

+0

@andrewf - Tôi đã kiểm tra trang trong Chrome và không thể thấy bất kỳ lỗi rõ ràng nào - pub là giao diện công cộng - tôi gọi init trong tài liệu.đã có sẵn –

Trả lời

0

Phương pháp đầu tiên populates biến vì nó thực hiện:

var pub = {}, $ctl = $("#loan-selector"), 
    $sliderAmount = $ctl.find(".slider-amount:first"), 
    $widgetAmount = $sliderAmount.find(".widget:first"); 

Vì vậy #loan-selector, .slider-amount:first.widget:first cần phải được trả lại trong DOM của trang trước khi điều này được gọi.

Biến thể thứ hai phổ biến khi được gọi là loanSelector.init() và bởi vị trí trong mã của bạn nơi bạn gọi nó là DOM được tải.

<asp:ScriptManager> cung cấp cho bạn bộ sưu tập các nút điều khiển tập lệnh phía máy chủ có thể thêm dễ dàng, nhưng nó hiển thị danh sách các thẻ <script> và thứ tự có thể quan trọng - một điều khiển khác trong trang có thể có nghĩa là DOM bạn đang dựa vào hasn không được tải theo thời gian mã của bạn chạy. Các tập lệnh chạy theo thứ tự nhưng không đợi hiển thị DOM kết thúc. Bạn có thể sử dụng nó trong DefaultInit.js, đó là lý do tại sao loanSelector.init() có thể truy cập DOM trong khi mã thực hiện trực tiếp không không phải.

Bạn đã có bản sửa lỗi và tập lệnh thứ hai của bạn là thực hành tốt hơn vì nó không phụ thuộc vào thời gian thực thi.

Một lựa chọn khác sẽ được gọi loanSelector chức năng của bạn trong $(document).ready:

$(function(){ 
    // In this DOM ready function your elements should be ready to find 
    var loanSelector = ... 
    ... 

    // And you may not need this, as you can init in the actual function 
    loanSelector.init(); 
}); 
Các vấn đề liên quan