как использовать шаблон модуля 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, объявить мои vars, добавить addMessage функция с вызовом ajax. и вызовите

5 ответов


Это довольно самоуверенный предмет, но я бы сделал это (не полностью зная ваше полное приложение и что оно делает), примерно так:

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 оператор работает в этом контексте, если вы немного смущены этим, что может быть стоит прочитать тоже.


шаблон модуля выявления используется следующим образом:

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();

У меня есть некоторый опыт работы с Mootools, но я новичок в jQuery. Я прочитал документы, и похоже, что самый умный способ организовать код-это шаблон модуля, поэтому я пробую это. Однако одна вещь, которая, кажется, отсутствует в этом стиле, - это любое понятие "я", поскольку каждая переменная в жизни является самодостаточным объектом (без каламбура).

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

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
    }

})();

что мне нравится в этом, так это то, что я могу внутренне ссылаться на все методы и свойства, используя "self". Я все еще могу раскрыть методы, которые я хочу использовать, используя объект "return", так что (я думаю) это нормально. Но я такой новичок, и это кажется таким простым и (на первый взгляд) элегантным, что мне, должно быть, не хватает майора gotcha. Он разделяет стиль кодирования с Литеральным форматом объекта, который мне знаком с из Mootools. Так что, возможно, я пытаюсь вставить круглый колышек в квадратное отверстие. Возможно, литерал внутреннего объекта не нужен, потому что вместо "Я".doSomething ()", я могу просто сказать"doSomething"? Это так?

частично мне это нравится, потому что я могу установить аргумент "context"$.Аякс - это "я", что кажется победой.


идея состоит в том, чтобы сократить видимость из внешнего мира и улучшить управление кодом, разделив ваш код на сегменты/модули.Проверьте это, если вы хотите увидеть действительно хорошее использование шаблона модульного проектирования и какой-то способ получить от него выгоду.
http://learn.jquery.com/code-organization/concepts/


В отличие от JAVA, Javascript не имеет понятия private и public по свойствам или по методам. Давайте создадим объект person, который имеет 2 свойства firstName и lastName, а также создадим 2 функции, которые будут геттерами для наших свойств. В 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, C++, как языки). Наши намерения хороши, позволяет применять понятия, специфичные для Javascript. Мы не хотим делать лица.firstName, мы хотим, чтобы запретить доступ к свойству напрямую. В таких языках, как JAVA, из-за частного и публичного мы достигли контролируемые свойства, но в Javascript все общедоступно.

Javascript использует концепцию закрытия для реализации таких вещей, как private & public. Этот шаблон называется шаблоном модуля. То есть сокрытие переменных от публичного доступа. Чтобы реализовать области, оберните свои коды в функцию (помните, что области реализуются через функции в 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 не запоминает variabes, но функцию объекты запоминаются из-за замыканий. Похоже, мы достигли того, чего хотели, но осталось одно, и это сеттеры для контролируемого доступа 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/