2015-12-17 3 views
-1

Я создал следующие три модуля. Вопрос заключается в том, что с помощью IIFE (без использования модульной библиотеки, такой как common.js, require.js и т. Д.), Как это сделать так, чтобы только модуль2 был видимым для модуля3, и только модуль1 должен быть видимым для модуля2.Контроль Visibliy с использованием IIFE

Q2. Как избежать того, чтобы модули 1 и 2 поступали в глобальную область действия, так как мне нужно выставить ТОЛЬКО mondule3, который будет доступен из html?

module1.js
var module1 = (function(){ 
    var module1Msg = "This is Module 1"; 

    return { 
    module1Msg:module1Msg 
    }; 
})(); 

module2.js
var module2 = (function(){ 
    var module2Msg = module1.module1Msg +" - "+" This is Module 2"; 

    return { 
     module2Msg:module2Msg 
    }; 
})(); 

module3.js
var module3 = (function(){ 
    var module3Msg = module2.module2Msg +" - " +" This is Module 3"; 

    return { 
    module3Msg:module3Msg 
    }; 
})(); 

и использующие эти модули из следующего HTML-файла

<html> 
<head> 
<title>Module Experiment</title> 
<script src="module1.js"></script> 
<script src="module2.js"></script> 
<script src="module3.js"></script> 

<script> 
    alert(module3.module3Msg); 

</script> 
</head> 
<body> 
<div id="display"></div> 

</body> 
</html> 
+2

Вы запрашиваете функциональность AMD , но не хотите использовать библиотеку AMD. Почему бы и нет?Во всех случаях будут задействованы некоторые накладные расходы, независимо от того, используете ли вы библиотеку AMD на стороне клиента, серверный узел, такой как браузер, или сворачиваете свое собственное решение. –

ответ

1

Ну, вы можете выполнить загрузку модуля самостоятельно. Вы можете использовать загрузку модуля, создав функцию, которая загружает файлы javascript для вас, у вас больше не будет ваших тегов скрипта внутри вашего html (кроме вашего стартового приложения).

В качестве примера, вы могли бы сделать что-то подобное, как:

<html> 
<head> 
<title>Module Experiment</title> 
<script> 
    'use strict'; 
    var scriptBase = './js/'; 
    var scriptcounter = 0; 

    function require(arr, callback) { 
     var requested = 0, loaded = 0; 
     arr.forEach(function(script) { 
      var scriptTag = document.createElement('script'); 
      scriptTag.id = 'myscript' + (++scriptcounter); 
      requested++; 
      scriptTag.addEventListener('load', function() { 
       loaded++; 
       if (loaded === requested) { 
        callback(); 
       } 
      }); 
      scriptTag.src = scriptBase + script + '.js'; 
      document.head.appendChild(scriptTag); 
     }); 
    } 

    window.addEventListener('load', function() { 
     require(['module1'], function() { 
      require(['module2'], function() { 
       require(['module3'], function() { 
        // everything loaded 
        console.log('I can call module3 here'); 
        var el = document.getElementById('display'); 
        el.innerHTML = module3.module3Msg; 
       }); 
      }); 
     }); 
    }); 
</script> 
</head> 
<body> 
<div id="display"></div> 

</body> 
</html> 

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

Эта функция также может быть названа как require(['module1', 'module2', 'module3'], function() { ... }), но вы, возможно, есть проблема, которая module2 будет загружаться до того module1, который приведет к недостающей эталонной ошибке, поэтому, именно поэтому я написал требует кода, указанного выше в 3 различных требуют утверждения. (это вы все еще можете использовать в своей текущей настройке. Непонятно, какой сценарий будет приниматься онлайн первым, так что это может быть ваше приложение будет работать на 90% и дать некоторые трудности с воспроизведением ошибок других 10%.

Вы может сделать это проще, по крайней мере, «определив» ваши модули в общем классе, а затем введя некоторые классы на основе их идентификатора строки, но я думаю, что это выходит за рамки вашего вопроса.

+0

Отлично, мне нравится, как вы объяснили. На самом деле я знаю лучший способ использовать либо common, либо require.js для решения этой проблемы, но мне просто интересно, как решить проблему с помощью простого Java-скрипта. и вы это сделали. благодаря – ATHER

-1

Просто передайте ссылку на модуль как параметр для конкретного iife. Передать модуль2 в модуль3 как параметр и сделать то же самое с модулем1 и модулем2

+0

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

0

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

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


Вы можете ограничить модуль, помещая всю его определение в () в конце другого модуля (и захватив его в качестве аргумента), но тогда вы не могли держать их в отдельных файлах.

Смежные вопросы