Конвертировать декоратор в пользовательский виджет в DOJO?

1

Я хотел бы узнать, можно ли преобразовать мою функцию decorator в пользовательский виджет (на основе dijit/form/Select), чтобы применить патч обезьяны.

Или вы знаете альтернативное решение?

require([
  'dijit/form/Select',
  'dojo/_base/window',
  'dojo/domReady!'
], function(Select, win) {
  var decorator = function(select) {
    select.on('change', function(value) {
      alert(value);
    });

    select.dropDown._onUpArrow = function() {
      this.focusPrev()
    }.bind(select.dropDown);

    select.dropDown._onDownArrow = function() {
      this.focusNext()
    }.bind(select.dropDown);

    select.dropDown.focusNext = function() {
      var focusNext = function() {
        var next = this._getNextFocusableChild(this.focusedChild, 1);
        this.focusChild(next);
        if (next.option.group) {
          focusNext();
        }
      }.bind(this);
      focusNext();
    }.bind(select.dropDown);

    select.dropDown.focusPrev = function() {
      var focusPrev = function() {
        var prev = this._getNextFocusableChild(this.focusedChild, -1);
        this.focusChild(prev);
        if (prev.option.group) {
          focusPrev();
        }
      }.bind(this);
      focusPrev();
    }.bind(select.dropDown);

    select.dropDown.onItemHover = function(item) {
      if (item.option.group) {
        item._set('hovering', false);
        return;
      }

      if (this.activated) {
        this.set('selected', item);
        if (item.popup && !item.disabled && !this.hover_timer) {
          this.hover_timer = this.defer(function() {
            this._openItemPopup(item);
          }, this.popupDelay);
        }
      } else if (this.passivePopupDelay < Infinity) {
        if (this.passive_hover_timer) {
          this.passive_hover_timer.remove();
        }
        this.passive_hover_timer = this.defer(function() {
          this.onItemClick(item, {
            type: 'click'
          });
        }, this.passivePopupDelay);
      }

      this._hoveredChild = item;

      item._set('hovering', true);
    }.bind(select.dropDown);

    select.dropDown._onItemFocus = function(item) {
      if (item.option.group) {
        return;
      }
      if (this._hoveredChild && this._hoveredChild != item) {
        this.onItemUnhover(this._hoveredChild);
      }
      this.set('selected', item);
    }.bind(select.dropDown);
  };

  var select = new Select({
    name: 'select2',
    options: [{
        label: '<i>Colors I love</i>',
        value: 'G 1',
        group: true,
        disabled: true
      },
      {
        label: 'Red',
        value: '1'
      },
      {
        label: 'Green',
        value: '2',
        selected: true
      },
      {
        label: 'Yello',
        value: '3'
      },
      {
        label: 'Purple',
        value: '4'
      },
      {
        label: '<i>Food I love</</i>',
        value: 'G 2',
        group: true,
        disabled: true
      },
      {
        label: 'Red tomatoes',
        value: '1'
      },
      {
        label: 'Green apples',
        value: '3'
      }
    ]
  }, 'select');

  decorator(select);

});
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dijit/themes/claro/claro.css" />

<script>
  window.dojoConfig = {
    parseOnLoad: false,
    async: true
  };
</script>


<script src="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dojo/dojo.js">
</script>

<body class="claro">
  <div id="select"></div>
</body>

Код, взятый из этого ответа;

Теги:
dojo
dijit.form

1 ответ

2
Лучший ответ

Если вы хотите создать пользовательскую форму, выберите js-виджет в своем проекте, без этого декоратора,

Для повторного использования Создайте JS файл (например, app/path/MyCustomSelect.js) (убедитесь, что вы настроили свое додзе, чтобы найти созданный файл, см. Здесь в документации), после импорта ресурса (использование AMD define) создайте виджет и наследуйте выберите, используя класс declare,

На данном этапе, вы должны ovveride в пост -создания (метод базового виджета lifcycle, это выполняется после создания экземпляра и перед rendring), а затем добавить код вы декоратора (путем замены select в текущей области this),

Зачем использовать postcreate, поскольку создается виджет, и создаются все другие ссылки ressouce, поэтому вы можете получить доступ к this.dropDown свойству this.dropDown, которое невозможно в методе конструктора, см. Выше ссылку, чтобы лучше понять фазы жизненного цикла виджета.

После использования виджета в вашем приложении, используя require ("location_to_your_jsile"), и используйте его ссылку в обратном вызове,

Поэтому файл MyCustomSelect.js должен выглядеть так:

define([
  "dojo/_base/declare",
  'dijit/form/Select',
], function(declare, Select) {

  return declare(Select, {
    postCreate: function() {
      //make sur call this , like call super() ; inherited code will be executed 
      this.inherited(arguments);

      console.log(this.dropDown);
      this.dropDown._onUpArrow = function() {
        this.focusPrev()
      }.bind(this.dropDown);

      this.dropDown._onDownArrow = function() {
        this.focusNext()
      }.bind(this.dropDown);

      this.dropDown.focusNext = function() {
        var focusNext = function() {
            var next = this._getNextFocusableChild(this.focusedChild, 1);
            this.focusChild(next);
            if (next.option.group) {
              focusNext();
            }
        }.bind(this);
        focusNext();
      }.bind(this.dropDown);

      this.dropDown.focusPrev = function() {
        var focusPrev = function() {
          var prev = this._getNextFocusableChild(this.focusedChild, -1);
          this.focusChild(prev);
          if (prev.option.group) {
            focusPrev();
          }
        }.bind(this);
        focusPrev();
      }.bind(this.dropDown);

      this.dropDown.onItemHover = function(item) {
        if (item.option.group) {
          item._set('hovering', false);
          return;
        }

        if (this.activated) {
          this.set('selected', item);
          if (item.popup && !item.disabled && !this.hover_timer) {
            this.hover_timer = this.defer(function() {
              this._openItemPopup(item);
            }, this.popupDelay);
          }
        } else if (this.passivePopupDelay < Infinity) {
          if (this.passive_hover_timer) {
            this.passive_hover_timer.remove();
          }
          this.passive_hover_timer = this.defer(function() {
            this.onItemClick(item, {
              type: 'click'
            });
          }, this.passivePopupDelay);
        }

        this._hoveredChild = item;

        item._set('hovering', true);
      }.bind(this.dropDown);

      this.dropDown._onItemFocus = function(item) {
        if (item.option.group) {
          return;
        }
        if (this._hoveredChild && this._hoveredChild != item) {
          this.onItemUnhover(this._hoveredChild);
        }
        this.set('selected', item);
      }.bind(this.dropDown);
    }
  });
});

Если вам нужен живой образец (без использования файла separte), см. Ниже фрагмент :).

require([
  "dojo/_base/declare",
  'dijit/form/Select',
  'dojo/_base/window',
  'dojo/domReady!'
], function(declare, Select, win) {

  var SelectGroup = declare(Select, {
    postCreate: function() {
      //make sur call this , like call super() ; inherited code will be executed 
      this.inherited(arguments);
      
      console.log(this.dropDown);
      this.dropDown._onUpArrow = function() {
        this.focusPrev()
      }.bind(this.dropDown);
     
      this.dropDown._onDownArrow = function() {
        this.focusNext()
      }.bind(this.dropDown);
      
      this.dropDown.focusNext = function() {
        var focusNext = function() {
            var next = this._getNextFocusableChild(this.focusedChild, 1);
            this.focusChild(next);
            if (next.option.group) {
              focusNext();
            }
        }.bind(this);
        focusNext();
      }.bind(this.dropDown);
      
      this.dropDown.focusPrev = function() {
        var focusPrev = function() {
          var prev = this._getNextFocusableChild(this.focusedChild, -1);
          this.focusChild(prev);
          if (prev.option.group) {
            focusPrev();
          }
        }.bind(this);
        focusPrev();
      }.bind(this.dropDown);
      
      this.dropDown.onItemHover = function(item) {
        if (item.option.group) {
          item._set('hovering', false);
          return;
        }

        if (this.activated) {
          this.set('selected', item);
          if (item.popup && !item.disabled && !this.hover_timer) {
            this.hover_timer = this.defer(function() {
              this._openItemPopup(item);
            }, this.popupDelay);
          }
        } else if (this.passivePopupDelay < Infinity) {
          if (this.passive_hover_timer) {
            this.passive_hover_timer.remove();
          }
          this.passive_hover_timer = this.defer(function() {
            this.onItemClick(item, {
              type: 'click'
            });
          }, this.passivePopupDelay);
        }

        this._hoveredChild = item;

        item._set('hovering', true);
      }.bind(this.dropDown);
      
      this.dropDown._onItemFocus = function(item) {
        if (item.option.group) {
          return;
        }
        if (this._hoveredChild && this._hoveredChild != item) {
          this.onItemUnhover(this._hoveredChild);
        }
        this.set('selected', item);
      }.bind(this.dropDown);
    }
  });
  

  var select = new SelectGroup({
    name: 'select2',
    options: [{
        label: '<i>Colors I love</i>',
        value: 'G 1',
        group: true,
        disabled: true
      },
      {
        label: 'Red',
        value: '1'
      },
      {
        label: 'Green',
        value: '2',
        selected: true
      },
      {
        label: 'Yello',
        value: '3'
      },
      {
        label: 'Purple',
        value: '4'
      },
      {
        label: '<i>Food I love</</i>',
        value: 'G 2',
        group: true,
        disabled: true
      },
      {
        label: 'Red tomatoes',
        value: '1'
      },
      {
        label: 'Green apples',
        value: '3'
      }
    ]
  }, 'select');

  //decorator(select);

});
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dijit/themes/claro/claro.css" />

<script>
  window.dojoConfig = {
    parseOnLoad: false,
    async: true
  };
</script>


<script src="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dojo/dojo.js"></script>

<body class="claro">
  <div id="select"></div>
</body>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню