2010-06-14 63 views
6

tl; dr: Làm cách nào để triển khai MVC trong JavaScript một cách rõ ràng?Model-View-Controller trong JavaScript

Tôi đang cố triển khai MVC bằng JavaScript. Tôi đã googled và tổ chức lại với mã của tôi vô số lần nhưng đã không tìm thấy một giải pháp phù hợp. (Mã chỉ không "cảm thấy đúng".)

Đây là cách tôi đang thực hiện nó ngay bây giờ. Nó cực kỳ phức tạp và là một nỗi đau để làm việc với (nhưng vẫn tốt hơn so với đống mã tôi đã có trước đây). Nó có cách giải quyết xấu xí để đánh bại mục đích của MVC.

Và kìa, sự lộn xộn, nếu bạn thực sự dũng cảm:

// Create a "main model" 
var main = Model0(); 

function Model0() { 
    // Create an associated view and store its methods in "view" 
    var view = View0(); 

    // Create a submodel and pass it a function 
    // that will "subviewify" the submodel's view 
    var model1 = Model1(function (subview) { 
     view.subviewify(subview); 
    }); 

    // Return model methods that can be used by 
    // the controller (the onchange handlers) 
    return { 
     'updateModel1': function (newValue) { 
      model1.update(newValue); 
     } 
    }; 
} 

function Model1(makeSubView) { 
    var info = ''; 

    // Make an associated view and attach the view 
    // to the parent view using the passed function 
    var view = View1(); 
    makeSubView(view.__view); // Dirty dirty 

    // Return model methods that can be used by 
    // the parent model (and so the controller) 
    return { 
     'update': function (newValue) { 
      info = newValue; 

      // Notify the view of the new information 
      view.events.value(info); 
     } 
    }; 
} 

function View0() { 
    var thing = document.getElementById('theDiv'); 
    var input = document.getElementById('theInput'); 

    // This is the "controller", bear with me 
    input.onchange = function() { 
     // Ugly, uses a global to contact the model 
     main.updateModel1(this.value); 
    }; 

    return { 
     'events': {}, 

     // Adds a subview to this view. 
     'subviewify': function (subview) { 
      thing.appendChild(subview); 
     } 
    }; 
} 

// This is a subview. 
function View1() { 

    var element = document.createElement('div'); 
    return { 
     'events': { 
      // When the value changes this is 
      // called so the view can be updated 
      'value': function (newValue) { 
       element.innerHTML = newValue; 
      } 
     }, 

     // ..Expose the DOM representation of the subview 
     // so it can be attached to a parent view 
     '__view': element 
    }; 
} 

Làm sao người ta thực hiện MVC trong JavaScript trong một cách sạch hơn? Làm thế nào tôi có thể cải thiện hệ thống này? Hay đây là con đường hoàn toàn sai lầm, tôi có nên theo một mô hình khác không?

+0

(bốn năm sau) Sử dụng AngularJS. –

+1

Nếu bạn chỉ cố gắng hiểu MVC hoạt động như thế nào trong Javascript, thì hãy hỏi cách triển khai nó là hoàn toàn hợp lý. Quá nhiều nhà phát triển sử dụng các khung công tác ngay bây giờ mà không thực sự hiểu cách chúng hoạt động. – NobodyReally

Trả lời

0

Thành thật mà nói, MVC không phù hợp với Javascript. Nó có thể hỗ trợ các nguyên tắc cơ bản cơ bản của thiết kế, chắc chắn - bạn có thể tạo giả để hoạt động như bộ điều khiển hoặc mô hình, hỗ trợ kế thừa cơ bản và bạn có thể thao tác hoặc tạo bất kỳ số phần tử DOM nào, nhưng có một mức giá mà bạn trả cho - ở trên cao, khả năng truy cập và khả năng sử dụng.

Theo ý kiến ​​của tôi, tôi xem xét Javascript nhiều hơn về tăng cường - tâm lý KISS tồn tại vì một lý do chính đáng. Nếu bạn quan tâm đến những cách tốt hơn để tổ chức mã của bạn, luôn có tùy chọn đóng gói chức năng liên quan thành các mô-đun (sic) và trừu tượng hóa các phần phù hợp. Ví dụ: tạo một nhà máy để thực hiện quản lý yêu cầu AJAX phức tạp hơn hoặc một giả để xử lý việc xử lý các loại dữ liệu tương tự. Sử dụng một hàm cơ sở tiêu chuẩn cho các bộ điều khiển, một mô hình khác cho các mô hình, vv, như các nguyên mẫu cho các cá thể mới của các đối tượng đó có thể thực hiện chức năng tương tự ... nhưng một lần nữa, nó sẽ chống lại hạt Javascript.

Tuy nhiên, nếu bạn đang mắc kẹt trên ý tưởng MVC chỉ vì lợi ích của cấu trúc, hãy xem xét một cái gì đó như sau:

;(function(window, $) { 
    /** 
    * Event Object 
    * A quick description goes here. 
    **/ 
    var Events = window.Events = { 
     'bindTrackables': function() { 
      $('a.trackable').live('click', function() { 
       if(!_gaq) 
        _gaq = []; 
       _gaq.push(['_trackPageview', '/ajax/foobar']); 
      }); 
     }, 
     'bindSomeEvent': function() { 
      // etc 
     } 
    }; 

    /** 
    * Data Cache 
    * I'll need to remember stuff later, so I store it here 
    **/ 
    var Cache = window.Cache = { 
     'data': {}, 
     'store': function(key, value) { 
      Cache.data[key] = value; 
     }, 
     'fetch': function(key) { 
      return Cache.data[key]; 
     } 
    }; 

    /** 
    * Request Object 
    * Stores native AJAX requests for later use 
    **/ 
    var Request = window.Request = { 
     'current_requests': [], 
     'send': function(url, type, data, callback) { 
      Request.current_requests.push($.ajax({ 
       'url': url, 
       'type': type, 
       'data': data, 
       'callback': callback 
      })); 
     }, 
    } 

    // add some private logic here 
})(window, jQuery); 

Đó là cực kỳ cơ bản, nhưng bạn sẽ có được ý tưởng. Mã mô-đun là chìa khóa ... trong JS, điều này quan trọng hơn việc buộc ứng dụng của bạn (hoặc ngôn ngữ) để phù hợp với một phong cách nhất định.

+1

Tôi hoàn toàn đồng ý với quan điểm của bạn, nhưng ứng dụng của tôi phức tạp (đó là một ứng dụng Gmail-esque - không phải là lớn, nhưng điểm vẫn còn). Ngay cả tổ chức tương tự như mô hình trong bài viết của bạn, mã đã là một mớ hỗn độn; Tôi phải tìm một số mô hình tổ chức để tôi không phát điên. Tôi không cần phải tuân theo MVC nếu nó là một rắc rối để thực hiện (tốt), nhưng trong trường hợp đó tôi cần một mô hình thay thế. –

6

Có ít nhất một số khung MVC được thiết lập và có thể sử dụng cho JavaScript JavaScriptMVCpureMVC. Có lẽ nhiều hơn nữa. Tôi đã sử dụng JavaScriptMVC cho trình duyệt dựa trên và các ứng dụng Air và tiếp tục quay trở lại với nó - nó có vấn đề của nó nhưng tôi đã tìm thấy nó khá hữu ích.
Còn có các giải pháp khác, hãy xem Sammy, một điều mới tôi đã nghe những điều tốt đẹp về. Tôi đã không sử dụng bản thân mình nhưng có ý định thử sớm. Tôi không biết đủ về nó để mô tả nó đúng cách, nhưng với tôi nó có vẻ giống như một bộ điều khiển phía trước mà hoạt động trên các tuyến đường, một hệ thống templating và các cửa hàng dữ liệu ReSTful. Tôi không chắc chắn nếu nó là MVC nhưng có thành phần tương tự.

Tôi phải không đồng ý với mway's answer. MVC có thể hơi khác nhau để thực hiện trong JavaScript nhưng lợi ích của nó rất quan trọng đối với organising this mess. Các mẫu thiết kế thường được liên kết với các ngôn ngữ OO không đi ra ngoài cửa sổ chỉ vì js không phải là lớp dựa trên.

Tôi có thể nói rằng MVC phù hợp hơn với các ứng dụng JavaScript hơn là các ứng dụng dựa trên yêu cầu (phía máy chủ).Những đối tượng đó có thể treo trong một thời gian trong một ứng dụng JavaScript trang - vài phút nếu không phải hàng giờ - và có cách tổ chức tốt tổ chức tương tác của họ sẽ làm cho mã của bạn mạnh mẽ hơn và dễ xử lý hơn. There are books on the subject.

Một vài điểm khác liên quan đến mã bạn đã đăng.

  • Đối tượng xem có trách nhiệm áp dụng trình xử lý sự kiện cho các phần tử DOM. Đây là công việc của bộ điều khiển. Chế độ xem chỉ hiển thị HTML - trình điều khiển lắng nghe các sự kiện và hành động tương ứng.
  • Mô hình của bạn dường như biết quan điểm của bạn. Lớp mô hình phải có kiến ​​thức tối thiểu về lớp xem (có thể được đăng ký là observers). Giữ cho mô hình của bạn sạch sẽ và cho đến thời điểm này, ý tôi là điểm kinh doanh - logic kinh doanh. Trong các ứng dụng js bạn chỉ có thể ủy quyền cho một lớp mô hình phía máy chủ nhưng điều quan trọng là sự tỉnh táo của bạn để giữ cho mô hình của bạn trở thành logic nghiệp vụ và không có gì khác. Logic ứng dụng là công việc của bộ điều khiển