2012-05-09 2 views
0

По общему признанию, я все еще новичок в Доджо, и я всегда был слабым в Javascript, поэтому извините и неряшливый код или язык здесь.Пользовательский виджет в пользовательском виджете

Я использую Dojo 1.7.1 с Spring Roo 1.2.1RELEASE. Я загружаю Dojo через CDM от Google.

Я некоторое время назад создал пользовательский просмотрщик эскизов изображений для использования на моем сайте, к которому я добавляю, добавляя модуль к моему djConfig в load-scripts.tagx Spring Roo, который запускается при каждой загрузке страницы. Виджет миниатюр не соответствует шаблону 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> 

Вот JS для thumbailer:

// 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); 
       }); 
      } 
     }); 
}); 

Однако, когда я запускаю новый компонент в Chrome, я получаю общую ошибку в dojo.js.uncompressed.js линии 1716. Послание ошибка «multipleDefine», и прикрепленный объект выглядит как мой ArtTableWidget. Я заметил, что, хотя этот объект был выкопан, этот элемент «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 Я обновил все модули, использующие информацию в ответе BuffaloBuffalo, за исключением вместо «путь» в dojoConfig я использовал следующее:

<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», но первый, похоже, пытается разрешить URL-адрес через CDN (сайт API Google API, связанный выше), последний, похоже, хочет полный путь. Я задвигаюсь, чтобы ввести полный путь, поскольку это кажется грязным способом сделать это. Я также попытался добавить путь к dojoConfig как таковой:

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

но это, похоже, не помогает вообще, в результате чего некоторые действительно неприятные ошибки в JS консоли Chrome.

Не использует dojo/text модули, если я правильно читаю here?

+0

Вы решили это? Пожалуйста, предоставьте информацию об этом! – saravanakumar

+0

Извините, я этого не сделал. Я закончил работу с jQuery для этого проекта, так как я никогда не мог понять, что происходит в Доджо-мире. – CodeChimp

+0

Спасибо за ваш ответ :) – saravanakumar

ответ

1

Трудно сказать, что вопрос точного есть, но несколько вещей, которые выскакивают на меня:

Объект djConfig должен быть назван dojoConfig, если вы используете 1.7 (dojoConfig все еще работает, но может а также обновить его).

Недвижимость должно быть обновлено до path. Если img.ArtThumbnailWidget и img.ArtTableWidget находятся в общем каталоге, вы можете просто использовать что-то вроде:

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

Вторая вещь смешанные унаследованных/драм стилей грузчиков в img.ArtThumbnailWidget. У вас 99% от стиля AMD. Все, что вам нужно сделать, это

  1. Удалить dojo.provide и dojo.requires
  2. обновления require([],function(){..}); быть define([],function(){..});
  3. ссылки Обновления в объявите использовать локальные переменные, а не глобал:

    //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 является белым при запутывании ArtTableWidget.

+0

djConfig - это старое имя. dojoConfig - это новое имя. См. Http://dojotoolkit.org/documentation/tutorials/1.7/dojo_config/. –

+0

Я посмотрел на эту точную страницу при вводе ответа. Должен быть включен при записи, поскольку фрагмент кода верен. Обновленный мой ответ был последовательным. – BuffaloBuffalo

+0

Спасибо BuffaloBuffalo. Я принял ваш совет, изменил пользовательские компоненты, которые у меня были, и теперь по крайней мере перешел к другой проблеме. Я получаю аналогичную ошибку, как указано выше, но теперь в dojo/parser из CDN. Кроме того, он не может найти мои локальные файлы шаблонов, когда я использую dojo/text! плагин ... его пытается разрешить «./» на URL CDN.Вместо этого я попытался использовать имя модуля вместо него, но, похоже, он вообще не использует модули. Тем не менее, я все еще пытаюсь что-то сделать, и буду отчитываться. – CodeChimp

0

Итак, да, здесь есть множество вещей, которые могут быть неправильными. Можете ли вы получить меньший пример для работы?

  1. Это определенно стоит проверить вкладку «Network» ваших инструментов разработчика браузера, чтобы увидеть, что он пытается загрузить. Это обычно помогает с разрешением модуля. Синхронизация (которая, как я думаю, вы есть), а не асинхронный режим также помогает в диагностике.
  2. Если вы регистрируете img/ArtThumbnailWidget в своих модулях, вместо img.ArtThumbnailWidget?
  3. В долгосрочной перспективе, вы можете зарегистрировать пакеты, а не модуль за модулем ...
  4. Вы должны быть в состоянии обратиться к додзе/текст! ./ шаблоны/ArtThumbnailWidget.html вместо додзё/текст! IMG /ArtThumbnailWidget/templates/ArtThumbnailWidget.html в вашем виджете, но это станет актуальным только после загрузки виджета. (Требование для вашего модуля обрабатывается относительно вашего модуля.)
Смежные вопросы