2012-05-09 11 views
0

필자는 여전히 Dojo의 초심자이며, 나는 항상 JavaScript가 약해서 변명 거리가 너무 길다.커스텀 위젯의 커스텀 위젯

Dojo 1.7.1을 Spring Roo 1.2.1RELEASE와 함께 사용하고 있습니다. Dojo를 CDM을 통해 Google에서로드하고 있습니다.

얼마전 필자는 내 사이트에서 사용할 사용자 정의 이미지 축소판 뷰어를 만들었는데, 각 페이지로드시 실행되는 Spring Roo의 load-scripts.tagx에서 모듈을 djConfig에 추가하여 포함 시켰습니다. 썸네일 위젯은 AMD 패턴을 따르지 않습니다. 왜냐하면 내가 제대로 작동하지 못했기 때문입니다. 여기

는 djConfig입니다 :

여기
<script type="text/javascript"> 
    var djConfig = { 
      parseOnLoad: false, 
      isDebug: false, 
      locale: '${fn:toLowerCase(userLocale)}', 
      modulePaths: { 
       "message": "${message_dojo_url}", 
       "img.ArtThumbnailWidget": "${artThumbnailWidget_dojo_url}", 
       "img.ArtTableWidget": "${artTableWidget_dojo_url}", 
      }, 
     }; 
    </script> 

가 thumbailer에 대한 JS입니다 :

// img.ArtThumbnailWidget 
dojo.provide("img.ArtThumbnailWidget"); 

dojo.require("dojo._base.declare"); 
dojo.require("dojo.parser"); 
dojo.require("dojo.ready"); 
dojo.require("dijit._WidgetBase"); 
dojo.require("dijit._TemplatedMixin"); 
dojo.require("dojox.image.LightboxNano"); 

// Create the widget 
require([ 
     "dojo/_base/declare", 
     "dojo/parser", 
     "dojo/ready", 
     "dijit/_WidgetBase", 
     "dijit/_TemplatedMixin", 
     "dojo/dom", 
     "dojo/dom-construct", 
     "dojo/on", 
     "dojo/text!img/ArtThumbnailWidget/templates/ArtThumbnailWidget.html", 
     "dojox/image/LightboxNano", 
     "dojo/domReady!" 
    ], function(declare, parser, ready, _WidgetBase, _TemplatedMixin, dom, domConstruct, on, template) { 

    dojo.declare("img.ArtThumbnailWidget",[dijit._WidgetBase, dijit._TemplatedMixin], { 
     /* Our properties will go here */ 

     // Art JSON object, default is null 
     art: null, 

     // Viewer ID (the username of the person looking at this image), which will default to null 
     viewerId: null, 

     // maxThumbnailSize is how large of an image to return for the thumbnail. The back-end will resize the thumbnail accordingly 
     maxThumbnailSize: 100, 

     // maxImageSize is how large of an image to return for the LightboxNano. The back-end will resize the image accordingly 
     maxImageSize: 500, 

     // Our template - important! 
     templateString: template, 

     // A class to be applied to the root node in our template 
     baseClass: "artThumbnailWidget", 

     // Specifies there are widgets in the template itself that need to be rendered as well 
     widgetsInTemplate: true, 

     // Competition-related vars 
     competitionUrlBase: null, 
     competitionButtonIconUrl: null, 

     /* This is called once the DOM structure is ready, but before anything is shown */ 
     postCreate: function() { 
      // Get a DOM node reference for the root of our widget 
      var domNode = this.domNode; 

      // Run any parent postCreate processes - can be done at any point 
      this.inherited(arguments); 

      if(this.art!=null && this.viewerId!=null && this.art.owner.name == this.viewerId) {  // If the view is the owner, add the toolbar 
       // TODO: We need to clean this up, make it "prettier", and make the URLs more generic 
       var toolbarNode = domConstruct.create("div", {}, this.containerNode); 

       if(this.competitionUrlBase!=null) { 
        var url = this.competitionUrlBase; 
        if(url.indexOf('?')<0) { // URL does not have a '?' 
         url = url+"?"; 
        } else { // URL has a '?', so we need to tack on and additional '&' 
         url = url+"&"; 
        } 
        url = url+"username="+this.art.owner.name+"&artPieceId="+this.art.id; 

        var compButtonNode = domConstruct.create("a", 
          { 
           href: url, 
          },toolbarNode); 
        var compButtonImg = domConstruct.create("img", 
          { 
           src: this.competitionButtonIconUrl, 
           width: this.maxThumbnailSize/4, 
           height: this.maxThumbnailSize/4, 
          },compButtonNode); 
       } 
      } 
     }, 

     /* This private method is used to re-set the node values when something changes */ 
     _resetNodeValues: function() { 
      if(this.art !=null) { 
       // Using our thumbnailNode attach point, set its src value 
       this.thumbnailNode.src = this.art.url+"?maxSize="+this.maxThumbnailSize; 
       this.thumbnailNode.alt = this.art.title; 
       this.thumbnailNode.width = this.maxThumbnailSize; 
       this.thumbnailNode.height = this.maxThumbnailSize; 

       // Now setup the link for the LightboxNano 
       var lightboxNano = new dojox.image.LightboxNano({ 
        href: this.art.url+"?maxSize="+this.maxImageSize, 
       },this.thumbnailNode); 
      } 
     }, 

     /* This is called anytime the "art" attribute is set. Consider is a "setter" method */ 
     _setArtAttr: function(av) { 
      if (av != null) { 
       // Save it on our widget instance - note that 
       // we're using _set, to support anyone using 
       // our widget's Watch functionality, to watch values change 
       this._set("art", av); 

       this._resetNodeValues(); 
      } else { 
       // We could have a default here...would be an error, since we 
       // shouldn't be calling this without an art object 
      } 
     }, 

     _setMaxThumbnailSizeAttr: function(ms) { 
      // Save it on our widget instance - note that 
      // we're using _set, to support anyone using 
      // our widget's Watch functionality, to watch values change 
      this._set("maxThumbnailSize", ms); 

      this._resetNodeValues(); 
     }, 

     _setMaxImageSizeAttr: function(ms) { 
      // Save it on our widget instance - note that 
      // we're using _set, to support anyone using 
      // our widget's Watch functionality, to watch values change 
      this._set("maxImageSize",ms); 

      this._resetNodeValues(); 
     } 
    });  // End of the widget 

}); 

는 지금은 다른 사용자 정의 구성 요소, 위의 작은 이미지의 테이블을 추가하려합니다. 새로운 코드는이 오래된 위젯을 참조해야하지만 작동시키지 못합니다.

(지금까지) 새 테이블 위젯 : 나는 크롬의 새로운 구성 요소를 실행할 때

// in "img/ArtTableWidget" 
define([ 
     "dojo/_base/declare", "dojo/parser", 
     "dijit/_WidgetBase", "dijit/_TemplatedMixin", 
     "dojo/dom", "dojo/dom-construct","img/ArtThumbnailWidget", 
     "dojo/text!./ArtTableWidget/templates/ArtTableWidget.html"], 
    function(declare,parser,_WidgetBase,_TemplatedMixin, dom, domConstruct, ArtThumbnailWidget, template) { 
     return declare("img.ArtTableWidget",[dijit._WidgetBase,dijit._TemplatedMixin], { 
      // Default values for the ArtTable 

      // The base URL to use for downloading the photos 
      artUrlBase: null, 

      // The base URL used for submitting competitions and the button URL 
      newCompetitionUrlBase: null, 
      newCompetitionButtonIconUrl: null, 

      // Indicates what params on the URL are used to control page 
      // and size. These will be appended to the URL as needed. 
      pageNumberParameterName: "page", 
      pageSizeNumberParameterName: "size", 

      // Holds the page and size 
      page: 1, 
      size: 15, 
      totalPages: 0, 

      columns: 3, 

      // Holds the current list of "art" 
      artList: [], 

      // The userid currently viewing 
      viewerId: null, 

      // Our HTML template 
      templateString: template, 

      baseClass: "artTableWidget", 

      // Specifies there are widgets in the template itself that need to be rendered as well 
      widgetsInTemplate: true, 

      // Functions // 

      postCreate: function() { 
       this._load(this.page); 
      }, 

      // Loads the given page 
      _load: function(pageToLoad) { 
       if(pageToLoad==null) { 
        pageToLoad=1; 
       } 

       // Generate the URL 
       genUrl = this.artUrlBase.indexOf("?")>=0 ? this.artUrlBase+"&page="+pageToLoad+"&size="+this.size : this.artUrlBase+"?page="+pageToLoad+"&size="+this.size; 

       // Make the call to the backend 
       dojo.xhrGet({ 
        url: genUrl, 
        handleAs: "json", 
        tableWidget: this, 
        load: function(data,ioArgs) { 
         this.tableWidget.page = data.page; 
         this.tableWidget.totalPages = data.totalPages; 
         this.tableWidget.artList = data.data; 

         this.tableWidget._updateTable(); 
        } 
       }); 
      }, 

      _updateTable: function() { 
       // Fix the buttons at the bottom 

       // Clear the artTable 
       domConstruct.empty(this.artTable); 

       // Loop through the art and build the rows 
       tableRow = tableRow = domConstruct.create("tr",{},this.artTable); 
       dojo.forEach(this.artList,function(art,index) { 
        if(index % columns == 0) { 
         tableRow = domConstruct.create("tr",{},this.artTable); 
        } 
        tableColumn = domConstruct.create("td",{style: { marginLeft: "auto", marginRight: "auto" }},tableRow); 
        var tnNode = new ArtThumbnailWidget({ 
         art: art, 
         viewerId: this.viewerId, 
         competitionUrlBase: this.newCompetitionUrlBase, 
         competitionButtonIconUrl: this.newCompetitionButtonIconUrl, 
        }); 
        tnNode.placeAt(tableColumn); 
       }); 
      } 
     }); 
}); 

는, 나는 dojo.js.uncompressed.js 라인 (1716) 메시지에서 일반 오류 오류는 "multipleDefine"이고, 첨부 된 Object는 내 ArtTableWidget으로 보입니다. 이 객체는 맨 위에 define()에 정의 된 모든 종속성의 배열 인 것으로 보이는 "deps"멤버가 img/ArtThumbnailWidget을 포함하지만 "pack"멤버는 정의되지 않은 것으로 나타났습니다. . 내 모듈이나 뭔가를로드하지 않고있는 것 같습니다.

오류 (복사/붙여 넣기를 잘 보이지 않는 경우 죄송합니다)입니다 :

dojo.js.uncompressed.js:1716 
Error 
    arguments: undefined 
    get stack: function getter() { [native code] } 
    info: Object 
    cacheId: 0 
    cjs: Object 
    def: function (declare,parser,_WidgetBase,_TemplatedMixin, dom, domConstruct, ArtThumbnailWidget, template) { 
    deps: Array[8] 
    0: Object 
    1: Object 
    2: Object 
    3: Object 
    4: Object 
    5: Object 
    6: Object 
     cacheId: 0 
     def: 0 
     executed: 4 
     injected: 2 
     isAmd: false 
     isXd: null 
     mid: "img/ArtThumbnailWidget" 
     pack: undefined 
     pid: "" 
     result: Object 
     url: "/ArtSite/resources/img/ArtThumbnailWidget.js" 
     __proto__: Object 
    7: Object 
    length: 8 
    __proto__: Array[0] 
    executed: 0 
    injected: 2 
    isAmd: false 
    isXd: null 
    mid: "img/ArtTableWidget" 
    node: HTMLScriptElement 
    pack: undefined 
    pid: "" 
    require: function (a1, a2, a3){ 
    result: Object 
    url: "/ArtSite/resources/img/ArtTableWidget.js" 
    __proto__: Object 
    message: "multipleDefine" 
    set stack: function setter() { [native code] } 
    src: "dojoLoader" 
    type: undefined 
    __proto__: ErrorPrototype 
    dojo.js.uncompressed.js:1719src: dojoLoader 
    dojo.js.uncompressed.js:1719info: 
    Object 
    dojo.js.uncompressed.js:1721. 

여기 바른 길에 돌아 가지 도움이 필요합니다.

EDIT 1 내가 대신 나는 다음과 같은 사용 dojoConfig에서 "경로"의 제외 BuffaloBuffalo의 응답의 정보를 사용하여 모든 모듈 업데이트 :

<script type="text/javascript"> 
    var djConfig = { 
      parseOnLoad: false, 
      isDebug: false, 
      locale: '${fn:toLowerCase(userLocale)}', 
      packages: [ 
       { name: "message", location: "${message_dojo_module_base_url}" }, 
       { name: "img", location: "${img_dojo_module_base_url}" } 
      ] 
     }; 
    </script> 

을 찾을 것으로 보인다. js 파일에는로드되지만로드 된 템플릿은 없습니다. dojo/text을 사용하십시오. 나는 "./path/Template.html"과 "/module/path/Template.html"을 시도했지만 처음에는 CDN (위의 링크 된 Google API 사이트)을 통해 URL을 확인하려고 시도하는 것으로 보이는데 후자는 완전한 경로. 나는 그것을하는 더러운 길과 같게 보이는 것에 따라 완전한 길을 넣기 위해 셔터를 난다. 나는 또한 같은 dojoConfig의 경로를 추가하는 시도 :

 paths: [ 
      { "message" : "${message_dojo_module_base_url}" } 
     ] 

을하지만 크롬의 JS 콘솔에서 정말 불쾌한 오류의 원인이 전혀 도움을 보이지 않았다.

올바르게 읽으면 dojo/text 모듈을 사용하지 마십시오. here?

+0

해결 방법이 있습니까? 이것에 대한 어떠한 업데이트도 제공하십시오! – saravanakumar

+0

미안하지만. 나는이 프로젝트를 위해 jQuery를 사용하지 못했고 Dojo-world에서 결코 물건을 찾아 낼 수 없었습니다. – CodeChimp

+0

답장을 보내 주셔서 감사합니다 :) – saravanakumar

답변

1

그것은 정확한 문제가 무엇인지 말해 어렵지만, 나를 뛰어 몇 가지 다음 djConfig 객체가 dojoConfig를 지정해야합니다

는 1.7 (dojoConfig를 사용하는 경우는 여전히 작동하지만 수도 뿐만 아니라 그것을 업데이 트).

modulePaths 속성은 path으로 업데이트해야합니다.

var dojoConfig = { 
      parseOnLoad: false, 
      isDebug: false, 
      locale: '${fn:toLowerCase(userLocale)}', 
      paths: { 
       "message": "${message_dojo_url}", 
       "img": "${art_module_url}" 
      } 
     }; 

두 번째 것은 img.ArtThumbnailWidget의 혼합 유산/AMD 로더 스타일입니다 : img.ArtThumbnailWidgetimg.ArtTableWidget 공통 디렉토리에있는 경우 당신은 같은 것을 사용할 수 있습니다. AMD 스타일로 99 %의 인기를 얻고 있습니다. 당신이해야 할 모든

  1. 제거 dojo.provide이며
  2. 갱신 require([],function(){..});은 전역이 아닌 지역 변수를 사용하는 선언에 define([],function(){..});
  3. 업데이트 참조로 dojo.requires :

    //ArtThumbnailWidget 
    define('img/ArtThumbnailWidget', [ 
        "dojo/_base/declare", 
        "dojo/parser", 
        "dojo/ready", 
        "dijit/_WidgetBase", 
        "dijit/_TemplatedMixin", 
        "dojo/dom", 
        "dojo/dom-construct", 
        "dojo/on", 
        "dojo/text!img/ArtThumbnailWidget/templates/ArtThumbnailWidget.html", 
        "dojox/image/LightboxNano", 
        "dojo/domReady!" 
        ], function (declare, parser, ready, _WidgetBase, _TemplatedMixin, dom, domConstruct, on, template) { 
    
        return declare("img.ArtThumbnailWidget", [_WidgetBase, _TemplatedMixin], { 
        /* Our properties will go here */ 
    
        // Art JSON object, default is null 
        art: null, 
    
        // Viewer ID (the username of the person looking at this image), which will default to null 
        viewerId: null, 
    
        // maxThumbnailSize is how large of an image to return for the thumbnail. The back-end will resize the thumbnail accordingly 
        maxThumbnailSize: 100, 
    
        // maxImageSize is how large of an image to return for the LightboxNano. The back-end will resize the image accordingly 
        maxImageSize: 500, 
    
        // Our template - important! 
        templateString: template, 
    
        // A class to be applied to the root node in our template 
        baseClass: "artThumbnailWidget", 
    
        // Specifies there are widgets in the template itself that need to be rendered as well 
        widgetsInTemplate: true, 
    
        // Competition-related vars 
        competitionUrlBase: null, 
        competitionButtonIconUrl: null, 
    
        /* This is called once the DOM structure is ready, but before anything is shown */ 
        postCreate: function() { 
         // Get a DOM node reference for the root of our widget 
         var domNode = this.domNode; 
    
         // Run any parent postCreate processes - can be done at any point 
         this.inherited(arguments); 
    
         if (this.art != null && this.viewerId != null && this.art.owner.name == this.viewerId) { // If the view is the owner, add the toolbar 
         // TODO: We need to clean this up, make it "prettier", and make the URLs more generic 
         var toolbarNode = domConstruct.create("div", {}, this.containerNode); 
    
         if (this.competitionUrlBase != null) { 
          var url = this.competitionUrlBase; 
          if (url.indexOf('?') < 0) { // URL does not have a '?' 
          url = url + "?"; 
          } else { // URL has a '?', so we need to tack on and additional '&' 
          url = url + "&"; 
          } 
          url = url + "username=" + this.art.owner.name + "&artPieceId=" + this.art.id; 
    
          var compButtonNode = domConstruct.create("a", { 
          href: url, 
          }, toolbarNode); 
          var compButtonImg = domConstruct.create("img", { 
          src: this.competitionButtonIconUrl, 
          width: this.maxThumbnailSize/4, 
          height: this.maxThumbnailSize/4, 
          }, compButtonNode); 
         } 
         } 
        }, 
    
        /* This private method is used to re-set the node values when something changes */ 
        _resetNodeValues: function() { 
         if (this.art != null) { 
         // Using our thumbnailNode attach point, set its src value 
         this.thumbnailNode.src = this.art.url + "?maxSize=" + this.maxThumbnailSize; 
         this.thumbnailNode.alt = this.art.title; 
         this.thumbnailNode.width = this.maxThumbnailSize; 
         this.thumbnailNode.height = this.maxThumbnailSize; 
    
         // Now setup the link for the LightboxNano 
         var lightboxNano = new LightboxNano({ 
          href: this.art.url + "?maxSize=" + this.maxImageSize, 
         }, this.thumbnailNode); 
         } 
        }, 
    
        /* This is called anytime the "art" attribute is set. Consider is a "setter" method */ 
        _setArtAttr: function (av) { 
         if (av != null) { 
         // Save it on our widget instance - note that 
         // we're using _set, to support anyone using 
         // our widget's Watch functionality, to watch values change 
         this._set("art", av); 
    
         this._resetNodeValues(); 
         } else { 
         // We could have a default here...would be an error, since we 
         // shouldn't be calling this without an art object 
         } 
        }, 
    
        _setMaxThumbnailSizeAttr: function (ms) { 
         // Save it on our widget instance - note that 
         // we're using _set, to support anyone using 
         // our widget's Watch functionality, to watch values change 
         this._set("maxThumbnailSize", ms); 
    
         this._resetNodeValues(); 
        }, 
    
        _setMaxImageSizeAttr: function (ms) { 
         // Save it on our widget instance - note that 
         // we're using _set, to support anyone using 
         // our widget's Watch functionality, to watch values change 
         this._set("maxImageSize", ms); 
    
         this._resetNodeValues(); 
        } 
        }); // End of the widget 
    }); 
    

나는 ArtThumbnailWidget에서 AMD의 스타일로 기존 스타일의 조합 어이다 의심 at에 혼동을 느낀다 ArtTableWidget.

+0

djConfig는 이전 이름입니다. dojoConfig는 새 이름입니다. http://dojotoolkit.org/documentation/tutorials/1.7/dojo_config/를 참조하십시오. –

+0

답변을 입력 할 때 정확한 페이지를 보았습니다. 코드 스 니펫이 올바르므로 서면으로 전환해야합니다. 일관되게 내 대답을 업데이트했습니다. – BuffaloBuffalo

+0

감사합니다 BuffaloBuffalo. 나는 당신의 충고를 받아들이고, 내가 가지고있는 맞춤 구성 요소를 변경했으며, 이제는 적어도 다른 문제로 옮겼습니다. 위와 비슷한 오류가 발생하지만 CDN의 dojo/parser에 있습니다. 또한 dojo/text를 사용할 때 내 로컬 템플릿 파일을 찾을 수 없습니다! 플러그인 ... 그 CDN URL에 "./"를 해결하려고합니다.모듈 이름 앞에 대신 붙이려고했지만 모듈을 전혀 사용하지 않는 것 같습니다. 나는 아직도 몇 가지 것을 시도하고 있으며, 다시보고 할 것이다. – CodeChimp

0

네, 여기에 잘못 될 수있는 많은 것들이 있습니다. 더 작은 예제를 사용할 수 있습니까?

  1. 그것을로드하려고 무엇 확인하기 위해서는 브라우저의 개발자 도구의 '네트워크'탭을 확인 확실히 가치가 입니다. 이는 대개 모듈 분석에 도움이됩니다. 비동기 모드가 아닌 동기화 기능 (내가 생각하기에)은 진단 기능을 도와줍니다.
  2. img.ArtThumbnailWidget 대신 modulePaths에 img/ArtThumbnailWidget을 등록해야합니까?
  3. 장기간에 걸쳐 모듈별로 패키지를 등록하는 것이 좋습니다.
  4. dojo/text! 대신 templates!/templates/ArtThumbnailWidget.html을 참조 할 수 있어야합니다. /ArtThumbnailWidget/templates/ArtThumbnailWidget.html 위젯에 있지만 위젯 로딩이 있으면 관련성이 높아집니다. 모듈에 대한 요구 사항은 모듈을 기준으로 처리됩니다.
관련 문제