2010-09-02 25 views
28

Tôi có trang có một số javascript cần chạy khi tải trang. Javascript nói cần phải xác định vị trí các thành phần phía máy khách của một ServerControl, mà nó làm với $ find().

Tất nhiên, nếu tôi phát trực tiếp mã của tôi lên trang, nó thực thi khi trang đang được đọc và không thành công vì không có gì tùy thuộc vào việc được khởi tạo.

Nếu tôi đặt mã của tôi bên trong một hàm pageLoad(), nó chạy tốt, vì asp.net tự động kết nối một trình xử lý tải lên cho bất kỳ hàm nào có tên pageLoad(). Vấn đề là tôi thực sự không thích giải pháp pageLoad() - chủ yếu là vì nó là một tên toàn cầu duy nhất. Nếu tôi thực hiện một số mã bằng cách sử dụng pageLoad(), tôi chỉ biết rằng một số lập trình viên khác sẽ sao chép phương pháp, một nơi nào đó không phù hợp và chúng tôi sẽ kết thúc với một trang bao gồm hai hoặc nhiều hàm pageLoad() khác nhau, và kết quả sẽ là một loạt các lỗi bí ẩn mà sẽ mất mãi mãi để theo dõi.

Vì vậy, tôi đặt mã của tôi bên trong một hàm ẩn danh được chuyển đến $ jquery (tài liệu) .ready(). Điều này không thành công, vì nó chạy trước khi thành phần phía máy khách của ServerControl tồn tại.

Vì vậy, tôi đặt mã của tôi bên trong một hàm ẩn danh được chuyển bởi Sys.Application.add_load(). Điều này cũng không thành công, bởi vì Sys là không xác định.

Vì vậy, cuối cùng tôi đã giải quyết việc đặt mã của mình bên trong Sys.Application.add_load(), và sau đó đặt nó bên trong một hàm được gọi bởi $ (document) .ready(). Điều này làm việc, nhưng nó cho gần như nhiều ợ nóng như pageLoad().

<script type="text/javascript"> 
    $(document).ready(function(){ 
     Sys.Application.add_load(function(){ 
      var component = $find(<clientid>); 
      if (component) { <do something> } 
     }); 
    }); 
</script> 

Phải có cách xử lý tốt hơn.

Bất kỳ ý tưởng nào?

Trả lời

20

Nếu bạn có quyền kiểm soát mã-đằng sau, bạn có thể đăng ký hoạt Javascript để chạy lúc khởi động thông qua một cái gì đó như:

this.Page.ClientScript.RegisterStartupScript(
    this.GetType(), 
    "StartupScript", 
    "Sys.Application.add_load(function() { functioncall(); });", 
    true); 

Chừng nào thành phần của bạn đã được tải qua Sys.Application.add_init() bạn nên ổn ...

+0

Điều đó có vẻ phù hợp với chúng tôi. –

3

Tôi tin rằng nếu bạn thêm (hoặc di chuyển) một điều khiển ScriptManager phía trên khối tập lệnh, bạn sẽ không cần phải bọc nó trong hàm $(document).ready() của jQuery. Bằng cách này rõ ràng Sys sẽ có sẵn như ScriptManager:

tiêm phần lớn JavaScript trong vị trí chính xác mà các ScriptManager kiểm soát được đặt ở trong trang. [http://encosia.com/2007/08/16/updated-your-webconfig-but-sys-is-still-undefined/]

Tuy nhiên, giải pháp này chắc chắn sẽ không rõ ràng đối với bất kỳ nhà phát triển không ngờ nào mà ScriptManager thực sự cung cấp ở đây.

Một phương pháp khác mà tham chiếu tập lệnh được thêm vào bên trong ScriptManager (xem "Cách tốt hơn" được thảo luận trong bài viết được liên kết ở trên) không được tốt lắm với tôi hoặc vì tôi không phải là người hâm mộ lớn của toàn bộ phương pháp ScriptManager.

5

Tôi muốn cung cấp giải pháp thay thế cho những người đang cố gắng xây dựng thư viện bên ngoài và cố gắng theo dõi tư duy javascript không phô trương càng nhiều càng tốt trong .NET.

pageLoad là một phương pháp tuyệt vời để tự động kết nối các sự kiện AJAX sẽ kích hoạt mọi tải trang (cho dù tải đó đến từ điều hướng nút quay lại trang này, điều hướng nút chuyển tiếp đến trang, gọi lại AJAX, tiêu chuẩn tải trang, vv), và vì bạn không phải lo lắng về việc chờ ScriptManager tồn tại trong DOM, và nó được đặt tên theo cách có ý nghĩa, hầu hết các phần (pageLoad vs. body.onload là hơi gây nhầm lẫn cho các lập trình viên .NET không, nhưng đối với một người .NET, có nghĩa là pageLoad sẽ kích hoạt tải trang EVERY, kể cả sau khi gọi lại, vì hành vi này giống hệt với phía máy chủ Page_Load). Điều đó đang được nói, mối quan tâm của bạn là những mối quan tâm tốt - bạn không muốn có hai trường hợp pageLoad trên một trang nhất định, vì nó sẽ phá vỡ. Đây là giải pháp javascript thẳng, an toàn cho các nhà phát triển của bạn, cho phép sử dụng pageLoad, không băn khoăn về DOM hiện có, đảm bảo không có xung đột mã và hoạt động tuyệt vời cho chúng tôi.

Trong thư viện javascript chính của bạn, xác định PageLoad, cũng như một hàm helper:

if (!pageLoad) { var pageLoad = function (sender, args) {}; }; 
if (!mylibrarynamespace) {var mylibrarynamespace = {};}; 
if (!mylibrarynamespace.registerStartupScript) mylibrarynamespace.registerStartupScript = function (fn) { 
    /* create local pointer for added function */ 
    var f = fn; 

    /* create pointer to existing pageLoad function */ 
    var pLoad = pageLoad; 

    /* add new function pointer to pageLoad by creating new anonymous function (search Google for "javascript enclosures" for why pl and f will persist with this newly defined anonymous function) */ 
    pageLoad = function (sender, args) { 
    pLoad(sender,args); 
    f(sender, args); 
    } 
} 

Sau đó, để sử dụng nó bất cứ nơi nào trong mã phía khách hàng của bạn, chỉ cần làm như sau:

mylibrarynamespace.registerStartupScript(
    function (sender, args){ 
     /* do my AJAX always enabled startup code logic here*/ 
    } 
); 

Để thay đổi chức năng dễ dàng hơn, tôi khuyên bạn nên chuyển qua chức năng ẩn danh trong một trang hoặc tập hợp con của thư viện để bạn chỉ cần thay đổi khai báo hàm của thư viện (trong tệp hoặc tại thời gian chạy) thay đổi cách trang eLoad cho phần cụ thể đó của trang web của bạn hoạt động.

+0

Nó là idomatic trong javascript để viết vài dòng đầu tiên của bạn như thế này: var pageload = pageload || function (sender, args) {}; – Goyuix

0

Hãy thử sử dụng ScriptManager để đăng ký khối tập lệnh khách, nhưng đặt tiêu đề duy nhất cho mỗi cuộc gọi hàm đặc biệt nếu nó có các tham số duy nhất nếu bạn đang sử dụng cùng một hàm nhưng với các giá trị tham số khác nhau. Nếu bạn sử dụng kỹ thuật add_load, nó chỉ nên được sử dụng khi tải trang không phải là bài đăng, tức là chỉ được gọi một lần sau khi làm mới trang hoặc tải trang mà không cần đăng lại.

hãy thử thay vào đó: ScriptManager.RegisterClientScriptBlock (đây, GetType(), "tiêu đề duy nhất", "cảnh báo ('kiểm tra nhanh');", đúng);

Các vấn đề liên quan