2012-04-24 2 views
31

나는 "새로운"브라우저 - 또는에 "오래된"브라우저 스타일의 모듈 구조에서 프로젝트를 변경하고있어 - 서버 사이드 자바 스크립트 모듈 구조는 require.js입니다. 내가 오프 사이트를 사용하고 클라이언트에 호출 방법

는 jQuery를 호스팅, 그래서 나는 그들이 README의 "use priority config" 기술에주는 예에서 시작 :

<title>My Page</title> 
<script src="scripts/require.js"></script> 
<script> 
require({ 
    baseUrl: 'scripts', 
    paths: { 
     jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min', 
     jqueryui: ..., 
     ... 
     ... // bunch more paths here 
    }, 
    priority: ['jquery'] 
}, [ 'main' ]); 
</script> 

이 실제로 모든 권리 노력하고 있습니다. 하지만 메인에서 HTML 웹 페이지로 기능을 내보내고 싶습니다. 예를 들어 :

<a class="button" href="#" onclick="MyApi.foo();"> 
    <img src="foo.png" alt="foo" />Click for: <b>Foo!</b> 
</a> 

는 AMD 모듈 패턴으로 피팅 전에, 나는 세계 공간에서 사전 개체를 만들어 내 다양한 ​​파일의 기능을 노출했던 :

// main.js 

var MyApi = {}; 

jQuery(document).ready(function($) { 
    // ...unexported code goes here... 

    // export function via MyApi 
    MyApi.foo = function() { 
     alert("Foo!"); 
    }; 
}); 

을하지만 나도 몰라 require.js의 올바른 접근 방식은 무엇입니까? HTML에 <script> 태그 안에 require 문을 넣은 다음 웹 페이지에서 사용할 수 있도록 모듈 이름을 지정해도됩니까? 아니면 항상 $('#foobutton').click(...)과 같이 main.js 내부에서 동적으로 수행해야합니까?

답변

30

AMD를 사용하면 얻을 수있는 이점 중 하나는 네임 스페이스의 필요성을 없애는 것입니다. RequireJS로 다시 만들려고하면 AMD가 추진하는 패턴에 어긋납니다.

main.js을 사용하는 것과 관련하여 단일 페이지 응용 프로그램과 모든 코드를 한 곳에서 참조 할 때만 적합합니다. 필요한 경우 다른 모듈을 필요로하고 추가로로드 할 수 있습니다. 페이지 요청에서 다음

foo.js

define(['jquery'], function($) { 

    // Some set up 
    // code here 

    // Return module with methods 
    return { 
     bar: function() { 

     } 
    } 


}); 

page.js

require(['foo'], function(foo) { 

    // jQuery loaded by foo module so free to use it 
    $('.button').on('click', function(e) { 
     foo.bar(); 
     e.preventDefault(); 
    }); 

}); 

: 위에서 당신의 예를 사용

, 당신은 이런 식으로 접근 할 수 require가있는 page.js 파일페이지를

<script> 
    require(['page']); 
</script> 

일부 추가 점

  • 을 위의 패턴을 사용 :

    위의 예를 사용 :

    require({ 
        // config stuff here 
    }, [ 'page' ]); 
    

    또는 더 아래 페이지에 넣기 .js는 쉽게 다른 많은 것을 요구할 수 있습니다. 모듈은 다른 페이지 관련 기능을로드합니다.

  • 도메인 이름 공간에 회원을 추가하기 전에 은 해당 코드를 페이지에서 다시 사용할 수있는 별도 모듈로 분리합니다. 모두 글로벌 객체에 의존하지 않습니다. 당신의 DOM 요소에 이벤트를 연결하려면이 방법을 필요로 사용

  • 은 RequireJS

    또한 자바 스크립트의 창 클래스에 대한 참조를 설정할 수 있습니다
+0

안녕하세요, 고마워요. (이 프로젝트로 돌아가서 대답을 자세히 살펴보십시오.) onclick에 코드를 넣는 것이이 방법론에 맞지 않는 이유를 단어로 표현합니다. 핸들러는 페이지의 HTML에 직접로드되는 모든 .js 파일에서 동일한 가져온 이름을 갖기 위해 호출하는 API를 필요로합니다. 그러나이 토큰에 의해 ...이 패턴에서, page.js가 jquery 매핑을'$'로 명시하는 대신에, foo가 그것을 가져온 것만으로 상속받는 것이 아니라면? – HostileFork

+0

필자는 항상 모듈을 재사용 가능하고 분류 된 코드라고 생각했습니다. 그러나이 접근 방식을 사용하면 모든 것이 모듈로 던져 져야하며 이벤트 바인딩과 같은 실제 모듈과 실제 모듈 간의 명확한 구분이 없습니다. 다른 방법이 없습니까? – backdesk

+0

질문에 DOM은 전역 MMyApi 개체에 의존합니다. 이 대답에서 페이지 모듈은 DOM에도 의존하며 이는 글로벌입니다. 어떤 종류의 의존성이 있어야합니다. 아마도 어느 것이 주관적인 선택일까요? –

3

마크 업 내부에 onclick=""을 넣는 것이 더러워진 것 같습니다. 콘텐츠와 프리젠 테이션을 혼합합니다. <script> 블록을 추가하고 그 안에 require을 넣은 다음 콜백 내부 및 다른 내부 내부에 $(document).ready()을 넣은 다음 정상적인 방법으로 이벤트 처리기를 연결하십시오 ($('#node').click(...)). 일반적으로 여러 페이지에 적용 할 수 있도록이 작업을 수행 할 수 있다면이를 축소, 결합 및 캐시 된 외부 파일에 저장하십시오. 하지만 일반적으로 이러한 것들은 페이지별로 이루어지기 때문에 페이지 하단의 <script> 태그는 다른 외부 리소스 요청을 피하기위한 좋은 해결책입니다.

+2

일을 * 며칠 전 : -) * ... 예, 프리젠 테이션과 콘텐츠에 대해, 웹 프로그래밍이 마치 막대기와 접착제처럼 느껴지더라도 복잡한 "모범 사례"의 구체적인 가치가 더 간단한 방법보다 더 중요하다는 사실을 알 수 있습니다. HTML5의 상용구에 대해서도 비슷한 결론을 내 렸습니다. "언제이 물건들을 우리 머리에 넣었습니까?" (http://csswizardry.com/2011/01/the-real-html5-boilerplate/) 그러나 @ SimonSmith의 * "require.js를 사용할 예정이라면 페이지 범위로 가져 오는 것이 좋지 않습니다. d는 "if A then B"방식으로 나에게 의미가 있습니다 ... – HostileFork

+0

개인적으로, 나는 검색 할 필요없이 버튼이 무엇인지 말할 수있는 유틸리티라고 생각합니다. 코드를 찾고 아마도 아직 그것을 찾지 못한다면, 그것을 분리하는 것의 이점을 강하게 압도 할 것입니다. "onclick"이 포함 된 버튼 태그를 보면 사용자가 해당 버튼을 클릭 할 때 어떤 일이 발생하는지 추측 할 수 없습니다. HTML은 순수한 프리젠 테이션이 아니며 결코 존재하지 않을 것입니다. – Jasmine

14

에 의해 rely on the DOM Ready module 가장 가능성이 제공됩니다. 응용 프로그램 모듈의 하단에서

window.MyApi = MyApi;

<a class="button" href="#" onclick="MyApi.foo();"></a>

2

그냥 같은 코드 (물론 requirejs 페이지에 추가해야합니다)를 사용하는 또 다른 솔루션 :

<input type="button" onclick="(function() { require('mymodule').do_work() })()"/>