Додзе, как переопределить метод класса dijit

Мне нужно переопределить метод onClick в Tree.js. Есть ли какой-нибудь общий способ переопределить методы классов dojo/dijit?

2 ответа

Решение

Вы можете использовать:

dojo.connect(tree, 'onClick', function(item) {
    /** Your Action **/
});

Я немного сбит с толку, так как вы уже делали это в последнем опубликованном вопросе.

У вас есть несколько вариантов, в зависимости от того, что вы хотите сделать.

Заглушки метода забивания

В случае настоящих окурков, таких как onClickпотенциально это так же просто, как забить этот метод на вашем экземпляре виджета.

Программный:

var myWidget = new dijit.Tree({
    ...,
    onClick: function(item, node, evt) {
        /* handler code here */
    }
};

Или декларативно (это точно так же, как вы делали в своем последнем вопросе):

<div dojoType="dijit.Tree" ...>
    <script type="dojo/method" event="onClick" args="item,node,evt">
        /* handler code here */
    </script>
</div>

Подключение к вызовам методов

В других случаях, возможно, вам нужно что-то делать всякий раз, когда вызывается данный метод, и в этом случае вы можете использовать виджет connect метод (который является более хорошей версией dojo.connect это автоматически очистит себя, когда виджет будет уничтожен). В этом случае вы можете сделать что-то вроде этого:

Программный:

//execute the given function whenever myWidget's onClick method is called
myWidget.connect(myWidget, 'onClick', function(item, node, evt) {
    /* handler code here */
});

Заявительно, это может быть сделано очень похоже на выше, за исключением того, что вместо type="dojo/method"убедитесь, что вы используете type="dojo/connect"

<div dojoType="dijit.Tree" ...>
    <script type="dojo/connect" event="onClick" args="item,node,evt">
        /* handler code here */
    </script>
</div>

Обратите внимание, что при таком подключении ваш код будет выполняться после того метода, к которому вы подключаетесь. Если вам нужно что-то сделать раньше, ваш лучший вариант, вероятно, dojo.declare ваше собственное расширение для виджета. Если вам нужно зайти так далеко, я уточню, но я думаю, что вы, вероятно, выберете один из вышеуказанных вариантов.

Редактировать #1: Соединение точек (не каламбур... о черт, да, это было)

Поскольку кажется, что мой комментарий, добавленный к моему ответу на исходный вопрос, был как-то недостаточно ясен, вот блок кода, модифицирующий исходный код в этом вопросе, основанный на двух простых шагах, в точности как я объяснил в этом комментарии. Единственная крошечная складка в том, что аргументы переданы _onClick немного отличаются.

<div dojoType="dijit.Tree" ...>
    <script type="dojo/connect" event="_onClick" args="node,evt">
        /* handler code here. In this case, item is accessible via node.item */
    </script>
</div>

Это решение может показаться немного неоптимальным, поскольку оно предполагает подключение к методу, который предполагается использовать в качестве частного. Тем не менее, это способ, который должен работать независимо от того, openOnClick это правда или нет. Если вы уверены, что у вас будет openOnClick установлен в true, вы могли бы написать одну функцию, а затем подключить ее к обеим onClick а также onOpen вместо этого (оба передают элемент, затем узел).

Правка № 2: Общие функции, подключаемые программно

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

Итак, во-первых, чтобы ответить на ваш connect вопрос: вы определенно не хотите использовать dojo.byId, поскольку это не дает вам виджет Tree, это дает вам некоторый DOM-узел (возможно, самый верхний), связанный с виджетом. Как общее правило, dojo методы ничего не знают о dijit вещи.

То, что вы действительно хотите сделать, это то, что я предложил выше. Здесь он применяется в соответствии с кодом, который вы пытались. Также обратите внимание, что onClick имеет заглавную букву C - еще одно общее правило: события виджетов используют нотацию верблюда, как способ отличить их от простых событий DOM, которые этого не делают.

var mytree = dijit.byId("mytree");
mytree.connect(mytree, "onClick", function(item) {
    /* ... */
});

Теперь, чтобы сделать этот шаг дальше и решить другой вопрос, если вы хотите связать некоторые общие функции с onClick а также onOpen а также onCloseВы можете сначала определить функцию, а затем подключить ее к обеим. Это одна из многих вещей, которая делает JavaScript потрясающим - доступность функций в качестве первоклассных объектов, которые можно легко обойти.

function handleClick(item) {
    /* do stuff here.
    Inside this function you can assume 'this' is the tree,
    since connect will ensure it runs in-context.
    */
}
var mytree = dijit.byId("mytree");
mytree.connect(mytree, "onClick", handleClick);
mytree.connect(mytree, "onOpen", handleClick);
mytree.connect(mytree, "onClose", handleClick);

Теперь остается один важный оставшийся вопрос: где мы должны это сделать? Лучшее место, вероятно, внутри функции, переданной dojo.ready (или же dojo.addOnLoad, то же самое, ready был добавлен как синоним в 1.4), так что он будет работать только после:

  • DOM анализируется браузером
  • Все dojo.required модули загружены
  • Если вы установите parseOnLoad: true в djConfigвсе виджеты, определенные в HTML-документе, будут уже созданы

Итак, когда-нибудь после вашего dojo.requires, в сценарии вы бы сделали это:

dojo.ready(function() {
    /* code from previous example goes here */
});

Дать ему шанс.

Кроме того, если вы хотите немного почитать, на самом деле я написал пару тем, которые затронули в этом редакторе:

Другие вопросы по тегам