2010-06-14 6 views
6

tl; dr : JavaScript로 MVC를 어떻게 구현하나요?JavaScript의 Model-View-Controller

JavaScript로 MVC를 구현하려고합니다. 나는 코드를 무수히하면서 봤지만 적절한 해결책을 찾지 못했다. (이 코드는 단지 "옳은 것"이라고 느끼지 않습니다.)

나는 지금 어떻게 할 것인가? 믿을 수 없을만큼 복잡하며 작동하기가 쉽지 않습니다 (그러나 이전에 가지고 있던 코드 더미보다 낫습니다). MVC의 목적에 어긋나는 추악한 해결 방법이 있습니다.

보라, 혼란, 당신이 정말로 용감 경우 :

// 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 
    }; 
} 
하나가 청소기 방법으로 자바 스크립트에서 MVC를 구현 않는 방법

? 이 시스템을 개선하려면 어떻게해야합니까? 아니면 다른 패턴을 따라야할까요?

+0

(4 년 후) AngularJS를 사용하십시오. –

+1

MVC가 Javascript에서 작동하는 방식을 이해하려는 경우, 구현 방법을 묻는 것이 매우 합리적입니다. 너무 많은 개발자들은 실제로 작동하는 방식을 실제로 이해하지 못하고 프레임 워크를 사용합니다. – NobodyReally

답변

0

사실 MVC는 Javascript에 적합하지 않습니다. 그것은 설계의 기본 원리를 지원할 수 있습니다. 여러분은 가상 클래스를 생성하여 컨트롤러 또는 모델로 작동하고 기본 상속을 지원할 수 있으며 모든 DOM 요소를 조작하거나 만들 수는 있지만 그 비용은 지불해야합니다. - 오버 헤드, 접근성 및 유용성.

제 의견으로는 자바 스크립트를 더 많이 사용한다고 생각합니다. 키스 정신은 좋은 이유가 있습니다. 코드를 구성하는 더 나은 방법에 관심이 있다면 관련 기능을 모듈로 패키징하고 적절하게 부분을 추출하는 옵션이 항상 있습니다. 예를 들어,보다 복잡한 AJAX 요청 관리를 수행하는 팩토리를 작성하거나 유사한 유형의 데이터 처리를 처리하는 가상 클래스를 작성하십시오. 컨트롤러를위한 표준 기본 함수를 사용하고 모델 등을위한 또 다른 프로토 타입을 사용하면 이러한 객체의 새로운 인스턴스를위한 프로토 타입을 만들 수 있습니다. 비슷한 기능을 수행 할 수는 있지만 다시 한번 자바 스크립트에 위배됩니다. 방금 구조를 위해 MVC의 아이디어에 부착하는 경우

그러나, 다음과 같은 고려 : 그것은 매우 기본이다

;(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); 

,하지만 당신은 아이디어를 얻을. 모듈 식 코드는 핵심 요소입니다. JS에서는 특정 스타일에 맞게 응용 프로그램 (또는 언어)을 강요하는 것보다 더 중요합니다.

+1

나는 귀하의 요점에 완전히 동의하지만, 제 신청서는 복잡합니다 (Gmail과 같은 약식 응용 프로그램입니다 - 큰 것은 아니지만 요점은 남아 있습니다). 귀하의 게시물에있는 모델과 유사하게 조직 된 코드는 엉망이었습니다. 그래서 나는 미쳐 가지 않았던 조직 모델을 찾아야했다. (잘) 구현하는 번거 로움이 있다면 MVC를 고수 할 필요는 없지만,이 경우에는 대체 패턴이 필요합니다. –

6

자바 스크립트 JavaScriptMVCpureMVC에 대해 몇 가지 설정되고 사용 가능한 MVC 프레임 워크가 있습니다. 아마 더 많은 것이 있습니다. 저는 JavaScript 기반의 브라우저와 Air 어플리케이션을 위해 JavaScriptMVC를 사용했고 계속해서 돌아 왔습니다. 문제가 있지만 꽤 유용하다고 생각했습니다.
다른 솔루션도 있습니다. Sammy을 살펴보세요. 좋은 점을 많이 들었습니다. 나는 자신을 사용하지 않았지만 곧 시도하려고합니다. 나는 그것을 적절하게 묘사하기에 충분하지는 않지만 나에게 그것은 루트, 템플릿 시스템 및 ReSTful 데이터 저장소에서 작동하는 프론트 컨트롤러처럼 보인다. 나는 MVC인지 모르지만 비슷한 성분을 가지고있다.

나는 mway's answer에 동의해야합니다. MVC는 JavaScript에서 구현하기에는 조금 다를 수 있지만 이점은 organising this mess에 매우 중요합니다. OO 언어와 관련된 디자인 패턴은 js가 클래스 기반이 아니기 때문에 창 밖으로 나가지 않습니다.

나는 MVC가 자바 스크립트 애플리케이션에 더 적합한 것은 요청 기반 (서버 측) 애플리케이션보다 적합하다고 말할 것이다.이러한 객체는 한 페이지 자바 스크립트 앱에서 잠시 멈출 수 있습니다. 몇 시간이 아니라도 몇 분이 걸립니다. 상호 작용을 체계적으로 정리하면 코드가 훨씬 강력하고 다루기 쉽습니다. There are books on the subject.

게시 한 코드와 관련된 몇 가지 요점이 있습니다.

  • 뷰 객체는 DOM 요소에 이벤트 리스너를 적용해야합니다. 이것은 컨트롤러의 일입니다. 뷰는 HTML을 렌더링합니다. 컨트롤러는 이벤트를 수신하고 그에 따라 작동합니다.
  • 귀하의 모델이 귀하의 의견을 알고있는 것 같습니다. 모델 계층에는 뷰 계층에 대한 최소한의 지식이 있어야합니다 (아마도 observers으로 등록되어있을 수 있습니다). 모델을 깨끗하게 유지하십시오. 비즈니스 포인트를 의미합니다. 비즈니스 로직입니다. js 애플 리케이션에서 당신은 단지 부서지기 쉬운 모델 계층에 대한 프록시일지도 모르지만 당신의 온전함이 당신의 모델을 비즈니스 로직으로 유지하는 것이 중요합니다. 응용 프로그램 논리는 컨트롤러 작업입니다.