Как использовать шаблон модуля javascript в реальном примере?
Я пытаюсь понять шаблон модуля JavaScript. Я видел примеры того, как он должен выглядеть, но я не понимаю, как его использовать.
Например, здесь происходит несколько вещей:
$('input#share').on("click", function() {
$('.loading').html('<img class="remove_loading" src="/graphics/loading.gif" />');
var message = $(".wallmessage").val();
if (message == ""){
$("#messageempty").jmNotify();
$('.remove_loading').remove();
} else {
addMessage(message);
}
return false;
});
function addMessage(message)
{
$.ajax({
url: '/test',
type: 'POST',
dataType: "json",
data: {'message' : message},
success: function(data) {
...
},
error: function() {
...
}
});
}
Как я могу использовать приведенный выше пример:
var myTest = function() {
var selectId;
function addMessage () {
// ...
}
return { // public interface
publicMethod1: function () {
// all private members are accesible here
}
};
};
var start = myTest();
Где добавить событие click, объявить мои вары, добавить функцию addMessage
с помощью вызова ajax. и вызовите функцию addMessage
? Мне нужно обернуть все в $(document).ready(function()
?
Может ли кто-нибудь пролить свет на это для меня?
Спасибо
Ответы
Ответ 1
Это довольно упрямый предмет, но я бы сделал это (не зная полного приложения и что он делает), примерно так:
var myApp = (function() {
var someElement = $("#foo"); //some element I know I'll use lots
var addMessage = function(message) {
$.ajax({
url: '/test',
type: 'POST',
dataType: "json",
data: {'message' : message},
success: function(data) {
...
},
error: function() {
...
}
});
};
var inputClick = function(event) {
event.preventDefault();
//depending on if you'll reuse these selectors throughout the app I might have these as variables
$('.loading').html('<img class="remove_loading" src="/graphics/loading.gif" />');
var message = $(".wallmessage").val();
if (message == ""){
$("#messageempty").jmNotify();
$('.remove_loading').remove();
} else {
addMessage(message);
}
};
var bindFunctions = function() {
$("input#share").on("click", inputClick)
};
var init = function() {
bindFunctions();
};
return {
// EDIT: 27/12/16 - need to return init for 'usage' example to work
init: init,
addMessage: addMessage
//anything else you want available
//through myApp.function()
//or expose variables here too
};
})();
//usage
myApp.init();
Исходный код шаблона неправильный, функция должна иметь ()
в самом конце, чтобы сделать его функцией, которая немедленно вызывается, а затем выполняется, выставляя что-либо через return statement
.
Возможно, вы захотите немного отличаться от того, что я сделал, это всего лишь базовая идея, но я надеюсь, что это может заставить вас начать.
Некоторое время назад задал вопрос, связанный с этим шаблоном, и Я ответил на него, объяснив, почему мы используем (function() {})();
и как работает оператор return
в этом контексте, если вы немного смущены тем, что тоже стоит прочитать.
Ответ 2
Схема раскрывающего модуля используется следующим образом:
var moduleName = (function () {
var privateVariable = 'private';
var privateMethod = function () {
alert('this is private');
};
// this is the "revealed" part of the module
return {
publicVariable: 'public',
publicMethod: function () {
alert('this is public');
}
};
}());
Вы также можете определить общедоступные переменные/методы как приватные, а затем выставить ссылку на них, сделав их общедоступными. Это вопрос предпочтения.
В вашем примере, если вы хотите, чтобы addMessage
был частью модуля, вы сделали бы это следующим образом:
var moduleName = (function () {
// this becomes public due to the reference exposure in the return below
var addMessage = function () {
// do whatever
};
// this is the "revealed" part of the module
return {
addMessage: addMessage
};
}());
moduleName.addMessage();
Ответ 3
У меня есть некоторый опыт работы с Mootools, но я начинающий jQuery. Я прочитал документы, и, похоже, самый умный способ организовать код - это шаблон модуля, поэтому я пытаюсь это сделать. Однако одна вещь, которая, кажется, отсутствует в этом стиле, - это любое понятие "я" , так как каждая переменная внутри IIFE является автономным объектом (каламбур не предназначен).
Итак... может быть, это побеждает целую цель, но вы могли бы сделать что-то подобное, и все-таки иметь это "действительное" во всех способах, которыми стиль шаблона модуля действителен?
var feature = ( function () {
var self = {
config: {
option1: 'thing 1',
option2: 'thing 2'
},
init: function (options) {
// allow overriding the default config
jQuery.extend( self.config, options );
self.doSomething();
},
doSomething: function () {
},
};
return {
init: self.init
}
})();
Что мне нравится в этом, так это то, что я могу внутренне ссылаться на все методы и свойства, используя "я" . Я все еще могу разоблачить методы, которые мне нужны, используя объект "return", поэтому (я думаю), что все в порядке. Но я такой новичок, и это кажется таким простым и (на первый взгляд) изящным, что мне, должно быть, не хватает основной информации. Он разделяет стиль кодирования с форматом Object Literal, с которым я знаком с Mootools. Так что, возможно, я пытаюсь вставить круглую привязку в квадратную дыру. Возможно, внутренний литерал объекта не нужен, потому что вместо "self.doSomething()" я могу просто сказать "doSomething"? Это так?
Частично мне это нравится, потому что я могу установить аргумент "context" для $.ajax как "я" , который кажется победой.
Ответ 4
Идея состоит в том, чтобы сократить видимость из внешнего мира и улучшить управление кодом, разделив ваш код на сегменты/модули. Проверьте это, если вы хотите увидеть действительно хорошее использование модульного шаблона проектирования и каким-то образом получить от этого выгоду.
http://learn.jquery.com/code-organization/concepts/
Ответ 5
В отличие от JAVA, у Javascript нет концепции частного и публичного доступа к свойствам или методам. Позволяет создать объект с именем person, который имеет 2 свойства firstName и lastName, а также создать 2 функции, которые будут getters для наших свойств. В Javascript мы можем создавать функции как свойства объектов, и эти функции доступны как любое другое свойство в любом месте.
var person={
"firstName":"Anoop",
"lastName":"Rai",
"getFirstName":function(){
return this.firstName;
},
"getLastName":function(){
return this.lastName;
}
};
console.log(person.getFirstName());
console.log(person.firstName);
Как и ожидалось выше, коды 11 печатают Anoop и Anoop. Хм, это плохо для объектно-ориентированного программирования. Ну, мы успешно реализовали геттеры, и поэтому у нас также должны быть сеттеры, которые должны быть общедоступными, а свойства должны быть помечены как закрытые области (что эти частные и публичные концепции принадлежат JAVA, С++, как языки). Наши намерения хороши, позволяют применять концепции, специфичные для Javascript. Мы не хотим делать person.firstName, мы хотим предотвратить доступ к собственности напрямую. В таких языках, как JAVA из-за частных и публичных, мы достигли контролируемого доступа к свойствам, но в Javascript все открыто.
Javascript использует концепцию закрытий для реализации таких вещей, как частные и публичные. Этот шаблон называется шаблоном модуля. То есть, скрывая переменные от открытого доступа. Чтобы реализовать области действия, заверните свои коды в функции (помните, что области применения реализованы через функции в Javascript).
function createPerson(){
var returnObj={
"firstName":"Anoop",
"lastName":"Rai",
"getFirstName":function(){
return this.firstName;
},
"getLastName":function(){
return this.lastName;
}
};
return returnObj;
}
var person=createPerson();
console.log(person.getFirstName());
console.log(person.firstName);
Теперь также над строками печатает Anoop и Anoop. Все еще нет успеха. Пока свойства привязаны к объекту, к нему будут обращаться напрямую. Давайте развяжем его. Вместо свойств мы делаем переменные области действия (замыкающие переменные).
function createPerson(){
var firstName="Anoop";
var lastName="Rai";
var returnObj={
"getFirstName":function(){
return firstName;
},
"getLastName":function(){
return lastName;
}
};
return returnObj;
}
var person=createPerson();
console.log(person.getFirstName());
console.log(person.firstName);
Теперь над строками печатается Anoop и undefined. Как это произошло? Из-за закрытий, когда были созданы функции getFirstName и getLastName, функции имели целую цепочку областей видимости или указатели на соответствующие переменные, то есть firstName и lastName. Объект returnObj не помнит переменные, но объекты функции запоминаются из-за закрытия. Похоже, мы достигли того, чего хотели, но осталось одно, и это сеттеры для контролируемого доступа firstName и lastName. Позволяет реализовать сеттеры.
function createPerson(){
var firstName="Anoop";
var lastName="Rai";
var returnObj={
"getFirstName":function(){
return firstName;
},
"getLastName":function(){
return lastName;
},
"setFirstName":function(name){
return firstName=name;
},
"setLastName":function(name){
return lastName=name;
}
};
return returnObj;
}
var person=createPerson();
console.log(person.getFirstName());
person.setFirstName("Kumar");
console.log(person.getFirstName());
Мы успешно модифицировали firstName, но контролируемым образом.
http://jkoder.com/the-module-pattern-javascript-way-of-hiding-data-in-objects-from-public-access/