2013-08-07 2 views
3

우리는 YUI3 로더를 사용하여 javascript 및 css 파일로드를 관리합니다. 각 페이지에 부트 스트랩 JS 코드의 일환으로, 우리는 다음과 같은 것이있다 :YUI 모듈을 지정할 때 YUI.add가 필요한 이유와 YUI 이외의 모듈이 작동하는 방법이 필요한지 알고 싶습니다.

YUI.add('my-module', function (Y) { 
    Y.MyModule = function() { 
     ... 
     _validator: Y.Lang.isString 
    }; 
}, '3.4.0', { 
    requires: [ "yui-base" ] 
}); 

YUI도 here을 로더가 될 수 있다는 주장 :

YUI({ 
    ... 
    groups: { 
    ... 
    myGroup: { 
     modules: { 
      "my-module": { 
       ... 
       path: "MyModule.js", 
       requires: [ "yui-base" ] 
      }, 
     } 
     ... 
    } 
    } 
}).use("my-module", function (Y) { 
    Y.MyModule.doStuff(); 
}); 

MyModule.js을 다음과 같은 뭔가가 구성에 종속성이 지정되어 있으면 YUI3이 아닌 "모듈"과 함께 사용됩니다.

 yui2: { 
      combine: true, 
      base: 'http://yui.yahooapis.com/2.8.0r4/build/', 
      comboBase: 'http://yui.yahooapis.com/combo?', 
      root: '2.8.0r4/build/', 
      modules: { // one or more external modules that can be loaded along side of YUI 
       yui2_yde: { 
        path: "yahoo-dom-event/yahoo-dom-event.js" 
       }, 
       yui2_anim: { 
        path: "animation/animation.js", 
        requires: ['yui2_yde'] 
       } 
      } 
     } 

이 유이로드하고 실행했다로드 만 야후-DOM-event.js 후 YUI2의 animation.js을 실행 똑똑 제안 : 그들은 yui2 그룹에 대한 다음 예제 모듈 구성을 제공합니다.

내가 이해할 수없는 것은 이것이 YUI 이외의 모듈에서 작동하는 경우 YUI.add를 사용하여 내 모듈을 포장해야하고 중복이 필요하다는 것입니다 (요구 사항 또한 구성에 지정되어 있기 때문에).

추가 래퍼를 삭제하려고 시도했지만 (페이지가 (function (Y) { /* module content */ })(YUI);으로 바뀜) 페이지로드시 js 오류가 발생합니다. Y.Lang은 정의되지 않았습니다. 따라서 wrapping add() 호출을하지 않아도 Y.Lang이 정의 된 기본 yui 스크립트 전에 스크립트가 실행되고있는 것으로 보입니다. 그러나 그렇다면 YUI가 아닌 모듈 (YUI.add()를 호출하지 않음)에서 문제가되지 않습니까?

답변

5

YUI3 기능 (샌드 박스 Y.Lang 등)을 사용하는 맞춤 모듈과 완전히 외부 코드를 구별하는 것이 중요합니다. 샌드 Y 변수 모듈 콜백 ​​(YUI.add() 두 번째 인수) 밖에 사용할 수 없기 때문에 제 경우

YUI.add() 랩퍼는 반드시 필요하다. 모듈 구성의 반복은 안타깝게도 손으로 쓰는 모듈에서는 Y.Loader (콤보 로딩 마술이 발생하는 곳) 내의 제약 때문에 필요합니다. YUI의 build tools을 사용하는 모듈은 래퍼와 메타 데이터를 자동으로 추가합니다.

외부 코드를 사용하면 fullpath 구성 속성 만 제공하면 YUI가 올바른 작업을 수행합니다. 내부적으로, YUI는 주어진 <script> 요청이 언제 끝나는 지 알고 있으며, 그 성공을 구성된 모듈 이름과 연관시킵니다.

편의를 위해 구성 비트를 보여주기 위해 YUI.applyConfig을 사용합니다. 이를 사용하여 장소 전체에 걸쳐 반복하지 않고 구성을 혼합 한 수의 YUI 샌드 박스 (YUI().use(...) 경유)를 만들 수 있습니다.

내-전단지-thing.js

YUI.applyConfig({ 
    "modules": { 
     "leaflet": { 
      "fullpath": "http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.js" 
     }, 
     "my-leaflet-thing": { 
      "path": "path/to/my-leaflet-thing.js", 
      "requires": [ 
       "base-build", 
       "node-base", 
       "leaflet" 
      ] 
     } 
    } 
}); 
이 같은 모습이 아닌 비동기 라이브러리를 필요로하기 때문에,이 설정을 감안할 때

YUI.add("my-leaflet-thing", function (Y) { 
    // a safe reference to the global "L" provided by leaflet.js 
    var L = Y.config.global.L; 

    Y.MyLeafletThing = Y.Base.create("myLeaflet", Y.Base, { 
     initializer: function() { 
      var id = this.get('node').get('id'); 
      var map = L.map(id); 
      // etc 
     } 
    }, { 
     ATTRS: { 
      node: { 
       getter: Y.one 
      } 
     } 
    }); 

// third argument is a version number, 
// but it doesn't affect anything right now 
}, "1.0.0", { 
    "requires": [ 
     "base-build", 
     "node-base", 
     "leaflet" 
    ] 
}); 

를 안전하게이 작업을 수행 할 수 있습니다

YUI().use("my-leaflet-thing", function (Y) { 
    var instance = new Y.MyLeafletThing({ 
     "node": "#foo" 
    }); 
}); 

참고 : 외부 파일이 자신의 동적로드를 수행하는 경우 (예 :, async Google Maps API), YUI는로드 된 전체 파일 체인이 아니라 초기 요청 성공만을 인식합니다. 이 문제를 해결하려면 fullpath 구성의 쿼리 문자열 콜백 인수를 사용해야하며 모듈을 필요로하는 일부 전역 적으로 노출 된 콜백과 관련이 있습니다.

이러한 경우에는 필요한 전역 변수를보다 잘 캡슐화하려면 Y.use() (샌드 박스 변수에 유의하십시오)을 사용하는 것이 좋습니다.

구성 :

YUI.applyConfig({ 
    "modules": { 
     "google-maps-api": { 
      "fullpath": "http://maps.googleapis.com/maps/api/js" + 
          "?v=3&sensor=false&callback=initGMapsAPI" 
     }, 
     "my-google-map-thing": { 
      "path": "path/to/my-google-map-thing.js", 
      "requires": [ 
       "base-build", 
       "node-base" 
      ] 
     } 
    } 
}); 

내 - 구글 -지도 - thing.js :

YUI.add("my-google-map-thing", function (Y) { 
    // publish a custom event that will be fired from the global callback 
    Y.publish('gmaps:ready', { 
     emitFacade: true, 
     fireOnce: true 
    }); 

    // private sentinel to determine if Y.use() has been called 
    var isUsed = false; 

    // expose global function that matches "callback" parameter value 
    Y.config.global.initGMapsAPI = function() { 
     // Y.config.global.google is now available 
     Y.fire('gmaps:ready'); 
    }; 

    Y.MyGoogleMapThing = Y.Base.create("myGoogleMap", Y.Base, { 
     initializer: function() { 
      Y.on('gmaps:ready', this.render, this); 
      if (!isUsed) { 
       isUsed = true; 
       Y.use("google-maps-api"); 
      } 
     }, 
     render: function() { 
      // safe reference to global "google" 
      var google = Y.config.global.google; 
      var id = this.get('node').get('id'); 
      var map = new google.maps.Map(id, { 
       // ... 
      }); 
      // etc 
     } 
    }, { 
     ATTRS: { 
      node: { 
       getter: Y.one 
      } 
     } 
    }); 

}, "1.0.0", { 
    "requires": [ 
     "base-build", 
     "node-base" 
    ] 
}); 

가 요약하면 : YUI3 샌드 박스 자원에 의존하는 모듈을 작성할 때 YUI.add()에만 필요합니다. 외부 코드를 로딩하는 것은 동 기적이면 모두 fullpath 구성 속성을 사용하는 것만 큼 간단합니다. 비동기 외부 로딩은 약간 더 털이 있지만 여전히 가능합니다.

+2

그렇다면 샌드 박스 모듈을 사용하려면 add()가 필요한 이유는 추가 콜백이 동 기적으로 호출되지 않으므로 초기 스크립트 실행 중에 Lang과 같은 모듈을 동 기적으로 사용하려고하면 그것은 아직 정의되지 않았을 것입니다. – ChaseMedallion

+0

정확히! 기본적으로,'YUI.add()'는 YUI의 전역 레지스트리에 지정된 이름으로 모듈 콜백을 등록합니다. 'YUI(). use()'는 전달한 모듈 이름 목록을 가져 와서 생성 한 샌드 박스 (콜백의'Y' 매개 변수)에 첨부합니다. –