Nano Hash - криптовалюты, майнинг, программирование

Публичный метод в плагине jquery не работает

Я написал следующий плагин с использованием JQuery, но не могу запустить общедоступный метод. Вместо этого я получаю сообщение в консоли:

«TypeError: $(...).panIt.doSomething не является функцией».

Мой код плагина выглядит следующим образом:

;(function() {

// custom panel class
$.fn.panIt = function(options) {

    var def = $.Deferred();
    var pan;

    var defaults = {
        container:        '<div class="panel_plugin"></div>',
        url:            '../../../js/plugins/myPanel/plugin.php',
        padding:        true,
        header:         {
                            isHeadline: false,
                            title:      null,
                            subTitle:   null,
                            minPanel: {
                                isAJAX:     false,
                                content:    ''
                            }
                        },
        footer:         false,
        body:        {
                            isAJAX:     false,
                            content:    ''
                        },
        allowScrolling: true,
        button:         {
                            toggle: true,
                            remove: true
                        },
        index:          null,
        panelSize:      'small',
        parent:         null, 
        domID:          null,
        buttons:       {
                        close: true,
                        sizeUp: true
        },
        onLoaded:       $.noop
    };

    var settings =  $.extend(true, defaults, options); // extend (i.e. merge) defaults with options passed across when plugin is invoked

    var deferredList = [];

    this.doSomething= function() { alert("coey"); };

    //Apply to each instance of the plugin
    this.each(function() {

        var innerDef = $.Deferred();
        addContainer(this);
        updateSettings(this);
        pan =  $(this).find("div.panel_plugin"); // reference for this plugin

        $.when ( loadPluginContent() ).done(function(result) {
            if(result === "success") {
                applySettings();
                setupPanEvents();
                console.log("Plugin html successfully loaded for index " + settings.index); // get count of stats plugins loaded on the page
                innerDef.resolve();
            } else {
                alert ("There was an error loading the plugin content for " + settings.index);
            } 
        });

        deferredList.push(innerDef.promise());
    });


    $.when.apply($, deferredList).done(function() {
        def.resolve("All of my inner defs have been resolved"); 
    });

    return def.promise();

};

}) (jQuery);

И когда я вызываю свой плагин, я использую это:

$('#total_membership').panIt({
        header:         {
                            title:      'Total Membership',
                            minPanel: {
                                isAJAX:     false,
                                content:    '<div class="panel-subtitle"> 12800</p>'
                            }
                        },
        body:           {
                            isAJAX: true,
                            content: 'membership_total.php'
        }
    });

А затем, чуть позже, я использую этот код, чтобы попытаться вызвать общедоступный метод:

$('#total_membership').panIt.doSomething();

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

Я новичок в плагинах JQuery, и я понимаю, что существует много разных шаблонов, но кто-нибудь может посоветовать мне, где я ошибаюсь? Многое оценил.

14.06.2018

  • Вы когда-нибудь инициализировали плагин? 14.06.2018
  • Нет, не знаю. Шаблон, из которого я взял свой код, не имел никакой функции инициализации. Как я могу это сделать? 14.06.2018
  • Кстати, плагин должен возвращать ту же коллекцию объектов, чтобы его можно было связать с другими функциями или плагинами jQuery. 14.06.2018
  • Спасибо за ответ. Я инициализирую его в своем первом фрагменте кода. Плагин эффективно создает красивый объект панели с заголовком, содержимым и т. д. После загрузки плагина есть определенные методы, которые я затем хочу вызвать. 14.06.2018
  • Итак, как мне вернуть обещание И тот же объект? 14.06.2018
  • Вы не можете. Вы должны сохранить экземпляр, а затем получить его, чтобы вызвать метод для этого экземпляра. 14.06.2018
  • Хорошо, я попытался прокомментировать строку кода Promise и вернуть this.each, но метод все еще не работает, и я все еще получаю ту же ошибку. 14.06.2018
  • Это может быть связано с порядком, в котором вы включаете файлы JavaScript. Попробуйте загрузить их в другом порядке или загрузить в конец HTML-файла, а не вверх. 14.06.2018
  • Спасибо, но плагин работает нормально, если я не включу метод, поэтому я думаю, что он не имеет ничего общего с порядком файлов. 14.06.2018
  • @ jmb.mage Нет, это не имеет ничего общего с файлами. 14.06.2018

Ответы:


1

Это базовый фрагмент/идея о том, как создать собственный плагин, чтобы позже иметь доступ к методам. Я добавил встроенные комментарии для пояснения.

В этом примере первая инициализация примет первый аргумент в качестве параметров объекта. Последние вызовы примут первый аргумент в качестве имени метода, а остальную часть аргумента — в качестве аргументов для метода.

Изменить

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

Определены два метода: chainable, который можно использовать с вызовом базового метода: $(selector).customPlugin('method', [arguments]) и метод nonChainable (как и статический метод, он не будет иметь доступа к выбранным элементам jQuery, но может выполнять любое другое базовое использование.

Итак, если вам нужно использовать элементы внутри метода, вам нужно использовать первый подход. Если методы являются просто вспомогательными и не будут использовать элементы dom плагина, определенные в запросе выбора, вы можете использовать второй подход.

Надеюсь, поможет.

$(function() {
	
	// Create custom plugin
	$.fn.customPlugin = function() {
		
		// Transforms the arguments to an array
		var args = Array.prototype.slice.call(arguments);
		
		// If the method is defined
		if($.fn.customPlugin.hasOwnProperty(args[0])) {
			
			// Execute the method, passed in first argument
			return $.fn.customPlugin[args[0]].apply(this, args.slice(1));
			
		} else {
			
			// Return all the matched elements so the function can be chained
			return this.each(function() {
				
				// If the plugin has not been initialized for the object
				if(typeof this.customStorage === 'undefined') {
					
					console.log('initialized');
					
					// Set data storage for the current element
					// This will allow to do any data storage for the element, and it will allow to check if the plugin has been initialized for the element
					this.customStorage = {};
					
					// Define custom options
					this.customStorage.options = $.extend(true, {}, $.fn.customPlugin.defaults, args[0]);
					
					// Do all your initialization sfuff...
					
				}
				
			});
			
		}
		
	};
	
	// Default options for the plugin
	$.fn.customPlugin.defaults = {
		message : 'default!'
	};
	
	// Chainable method, invoked by calling the main plugin method
	$.fn.customPlugin.chainable = function(message) {
		
		// If the method can be chained (applied to a jQuery element query)
		if(typeof this.each === 'undefined') throw { message : 'This method is chainable only' };
		
		// Return all the matched elements so the function can be chained
		return this.each(function() {
			
			// If the plugin has not been initialized for the object
			if(typeof this.customStorage === 'undefined') throw { message : 'You must initialize the plugin for the object to apply plugin methods to it' };
			
			$.fn.customPlugin.notChainable(this.customStorage.options.message, message);
			
		});
	};
	
	// Not chainable method
	$.fn.customPlugin.notChainable = function(messages) {
		
		// Can apply any action, but it does not have access to the elements of the jQuery element query
		
		console.log.apply(console, arguments);
		
	};
	
	// Initilizes the plugin
	$('#foo').customPlugin();
	
	// Initializes the option with a custom message
	$('#bar').customPlugin({ message : 'custom!' });
	
	// Then, later, call the custom method 'foo' with different arguments for each instance
	$('#foo').customPlugin('chainable', 'Message to log...');
	
	// Try to use a chaniable method by chaining
	try {
		$('#bar').customPlugin.chainable('Another message to log...');
	} catch(error) {
		console.log('Error!:', error.message);
	}
	
	//
	$('#bar').customPlugin.notChainable('A simple message to log...');
	
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo"></div>
<div id="bar"></div>

14.06.2018
  • Еще раз большое спасибо, muecas. Пожалуйста, не могли бы вы посоветовать, на что ссылается this.customStorage? Это связано с каким-то хранилищем данных? Где мне почитать об этом? Еще раз спасибо. Кроме того, еще один вопрос: можно ли как-то написать это, чтобы метод вызывался следующим образом: myplugin.method() ? 15.06.2018
  • @LeeA customStorage должен выполнять любое хранилище объектов и проверять, был ли плагин инициализирован для данного элемента. Это может быть что угодно, любое значение (хранилище данных, класс) или что-то еще, что сообщит выполнению функции, что плагин был инициализирован для элемента. И нет, вы не сможете позвонить plugin.method(). Метод должен выполняться в области действия элемента, поэтому вам нужно указать плагину, для какого элемента вы хотите выполнить метод. Вот почему его нужно вызывать внутри элемента: $('myelement').plugin('method'); для применения method к myelement. 15.06.2018
  • @LeeA просто любопытно, почему вы хотите так называть метод? 15.06.2018
  • Еще раз спасибо *muecas. Моя единственная причина, по которой я хочу называть это так, заключается в том, что так делают некоторые другие «сторонние» плагины, которые я использую. Но твой способ имеет смысл. Спасибо еще раз. 15.06.2018
  • @LeeA, вы могли бы сделать это таким образом, но вам понадобится более сложная структура плагина. 15.06.2018
  • Спасибо @muecas. «Простой» для меня лучше на данном этапе! :) 15.06.2018
  • @LeeA это решило твою проблему? Обратная связь приветствуется! :) 15.06.2018
  • Спасибо @muecas. Да, это ответило на вопрос для меня. Мне определенно нужно продолжать исследования и учиться, но ваш код дает мне хорошее решение, так что спасибо. 15.06.2018
  • @LeeA отлично!!, отметьте, если это решение :) 15.06.2018
  • Сегодня я провел еще несколько исследований и нашел статью, в которой рекомендуется использовать объект fn для добавления общедоступных методов и свойств: gabrieleromanato.name/ @meucas, один способ лучше другого? 16.06.2018
  • @LeeA Я не думал об этом в таком ключе. Позвольте мне изменить его, чтобы использовать предложенный шаблон из статьи. 16.06.2018
  • @LeeA вот оно. Вы настраиваете плагин, соответствующий вашим потребностям :-) 16.06.2018
  • Еще раз спасибо, @meucas. Просто хочу проверить мое понимание. Вы возвращаете self.each, но console.log(this...). Могу ли я использовать self или this в обоих случаях? Кроме того, есть ли причина для сохранения исходного метода, который вы предоставили (в отличие от этого нового метода)? Я где-то читал о том, что пространство имен JQuery нельзя вытягивать, но я действительно не знаю, что это значит! :) 16.06.2018
  • @LeeA позвольте мне проверить мое последнее редактирование. Я хочу внести в него некоторые изменения. И объяснить некоторые вещи. 16.06.2018
  • @LeeA Привет! Я добавил кучу улучшений. Я тестировал и исследовал. Прочитайте редактирование, а также встроенные комментарии. Это лучший подход, который интерфейс плагина jQuery может предложить для методов fot. Надеюсь, поможет. 19.06.2018
  • Извините за задержку ответа @muecas. Была большая помощь, поэтому просто хотел еще раз сказать спасибо 28.06.2018
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

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

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..