Fluent Interface внешнего .js
Впервые делаю текущий интерфейс, поэтому очень туплю. Нашел вот такой пример в википедии:
var Car = (function(){ var speed, color, doors, pub; function setSpeed(new_speed) { speed = new_speed; return pub; } function setColor(new_color) { color = new_color; return pub; } function setDoors(new_doors) { doors = new_doors; return pub; } pub = { 'setSpeed': setSpeed, 'setColor': setColor, 'setDoors': setDoors, }; return pub; }) // Обычная реализация myCar2 = Car(); myCar2.setSpeed(100); myCar2.setColor('blue'); myCar2.setDoors(5); // Текучий интерфейс myCar = Car(); myCar.setSpeed(100).setColor('blue').setDoors(5); Идею понимаю, мы возвращаем в конце каждой функции переменную на объект содержащий все поля которые мы соответственно в дальнейшем можем редактировать. А как будет выглядеть этот же самый пример если он будет внешний файлом? Может я чего не понимаю, но просто уже пару раз столкнулся с тем что из внешнего файла я перестаю видеть часть функций и т.п. |
Цитата:
|
Хм, ок, а такой вопрос, совсем наверное из основ для чайников:
var Car = (function(){ ... }) что означает такая запись? Var Car = {} - это объект fucntion Test(){} Var Car = Test - это функция даже пусть так: Var Car = Test(){} тоже функция (наверное, не проверял), но что означают круглые скобки вне функции (Test(){})? Насколько я понимаю это должно быть как то с видимостью переменных связано? Я к чему спрашиваю, у меня есть следующий код: (напишу абстрактно, так быстрее и понятнее. Создаю свое собственное контекстное меню) внешний.js 1.Документ готов: 2.Массив с пунктами и подпунктами Меню 3.Вспомогательные переменные (скорость появления и т.п.) 4.Создать несколько элементов div по клику на которые делать функцию Action 5.Вспомогательные функции нужные только для создания div 6.Функция Action 7.Отключаем контекстное меню 8.Добавляем обработчик правого клика мышки В результате я хочу получить собственную контекстую менюшку, и возможность ее редактировать в стиле: MyMenu.Size(30).Speed(10).AddMenu("Creat","Main"). AddMenu("Delete","Main") и т.п. Как мне лучше поступить? Насколько я понимаю по примеру из вики мне нужно поступить так: ... 3.Вспомогательные переменные (скорость появления и т.п.) var MyMenu=(function(){ функции обработки переменных (добавление изменение и т.п.) }) 4.Создать несколько элементов div по клику на которые делать ... Или же так: ... 1.Документ готов: var MyMenu=(function(){ 2.Массив с пунктами подпунктами Меню 3.Вспомогательные переменные (скорость появления и т.п.) функции обработки переменных (добавление изменение и т.п.) }) 4.Создать несколько элементов div по клику на которые делать ... Т.е. Если я создам свои переменные внутри функции MyMenu я же их не увижу снаружи, а значит придется и все функции создания div и Action засовывать внутрь функции MyMenu, а мне кажется это не правильно. |
Нафига там функция обернута в скобки ты спроси у тех, кто это писал, ибо там эти скобки никакой практической пользы не несут.
Суть чейнинга в том, чтобы из каждого метода возвращать объект у которого можно вызвать следующий метод. Цитата:
|
да по сути не зачем, просто у меня хреново с представление объектно-ориентированной модели того что я сейчас делаю, да и вообще(
Вообщем в качестве теста попробовал вот так: var myMenu = (function () { var pub function AddMenu(a,b) { for (var i=0;i<menuList.length;i++) if (menuList[i][1] == a) { menuList[i].push(b) menuList.push(b) } return pub } pub = { 'AddMenu': AddMenu, } }) Но когда я в основном файле пытаюсь обратиться к MyMenu он говорит что знать не знает о такой... Опять что-то с видимостью. Пробовал так window.BLABLA = myMenu не помогло, тоже не видит( |
Скрипты выполняются в том порядке, в котором они идут в HTML. Значит ты пытаешься обратится к MyMenu до того как был выполнен скрипт, который это самое MyMenu создает. Ну или действительно что-то с областями видимости у тебя не так. В общем сделай тестовый пример для большей конкретики.
|
Вот такой вот пример:
<!doctype html> <html> <head> <meta charset="UTF-8" /> <link rel="stylesheet" type="text/css" href="style.css"> <script src="jquery.js" type="text/javascript"></script> <script src="test.js" type="text/javascript"></script> <title>Menu</title> </head> <body id="menu"> <script> testFunction(); </script> </body> </html> test.js $( document ).ready(function() { function testFunction(){ alert("YES") } }); получаю ошибку: Uncaught ReferenceError: testFunction is not defined У меня есть мысль что это может быть потому, что код в test.js выполняется после того как вся страничка будет готова, а в основном хтмл файле он выполняется сразу, соответственно и не видит. Но тогда как решить эту проблему? |
... <script> $( document ).ready(function() {testFunction()}) </script> ... Попробовал вот так, получил вот что: Uncaught ReferenceError: testFunction is not defined test.html:12(anonymous function) test.html:12n jquery.js:2o.fireWith jquery.js:2e.extend.ready jquery.js:2c.addEventListener.C |
Ну так во-первых, у тебя тот код, что в body выполняется раньше чем тот что внутри ready в test.js, а во-вторых, доступа к testFunction у тбя всё равно не будет т.к. оно недоступно из вне. Сделай в test.js код без всякие ready и window.onload. Но вообще тебе явно надо подучить js, потому что насколько я вижу ты слабо представляешь как работают области видимости.
|
Так в том то и проблема что мне необходимо чтобы в test.js было .ready, да и тогда почему пример с $( document ).ready(function() {testFunction()}) не сработал, он же тоже должен выполниться, после того как все загрузится?
|
Цитата:
Цитата:
Цитата:
|
Как я понял тебе надо что-то вроде этого:
(function(){ var menuObj = { method1: method1, method2: method2, method3: method3 } function method1() { //some code return menuObj; } function method2() { //some code return menuObj; } function method3() { //some code return menuObj; } window.yourMenu = menuObj; $(document).ready(function() { //этот код будет выполнен после загрузки документа yourMenu.method1(); yourMenu.method2(); yourMenu.method3(); yourMenu.method1().method2().method3(); }); })(); Ну а еще лучше сделать полноценный конструктор. |
Цитата:
$(document ).ready(function() { ... }) вылезает ошибка на строке: menu.onmousedown = myDown; А если добавить $(document ).ready(function() { ... }) то все ок!!! вот полный код: var menu = document.getElementById('menu') menu.onmousedown = myDown; menu.onmouseup = myUp; menu.onmousemove = myMove; function myDown(e) { switch (e.button) { case 0: break case 2: switch (showMenu) { case false: xMenu = xMouse; yMenu = yMouse; showMenu = true; drawMenu() break case true: clearMenu(); break } break default: alert('Bad request'); break } } |
ААААААААА, ФАК ФАК ФАК ФАК, Я ЛООХ!
Кароче, да, вы были правы) Ошибка то вылезала потому что я скрипт подключал в head а там еще не существует элемента с id="Menu" >__________< Вообщем осталась последняя проблема которую так и не решил) У меня в menu.js нужно указать функцию которая будет описана в основном коде страничке, т.е. в index.html P.S.: Уже решил, в принципе все заработало и так, стоило описать функцию перед подгрузкой скрипта. Спасибо огромное за помощь, побольше вам жирных плюсов в репутацию!) |
Ну так и суй в ready только тот код, который должен непосредственно с DOM работать. В данном случае это вот этот код:
var menu = document.getElementById('menu') menu.onmousedown = myDown; menu.onmouseup = myUp; menu.onmousemove = myMove; |
А нет, кстати, что забавно все равно остался косяк который теперь мне тем более не понятен.
<script> function MyMenuActions(a) { alert(a)} </script> <script src="menu.js" type="text/javascript"></script> <script> myMenu </script> Так все ок, на myMenu не ругается, а вот если сделать myMeny.AddMenu("Main","New") Выдает ошибку, мол знать не знаю таких функций. В js эта функция выглядит так: window.myMenu = function () { var pub function AddMenu(a,b) { for (var i=0;i<menuList.length;i++) if (menuList[i][1] == a) { menuList[i].push(b) menuList.push(b) } return pub } pub = { 'AddMenu': AddMenu, } return pub } |
Ну так у тебя myMenu - это функция, у нее нет методов. Делай так:
window.myMenu = (function () { var pub function AddMenu(a,b) { for (var i=0;i<menuList.length;i++) if (menuList[i][1] == a) { menuList[i].push(b) menuList.push(b) } return pub } pub = { 'AddMenu': AddMenu, } return pub })(); |
ДА, вот теперь это решило проблему)
Спасибо огромное за потраченное на меня время!!!) |
Siend, функции принято с маленькой буквы называть. С большой называют классы (в JS - конструкторы).
|
Часовой пояс GMT +3, время: 10:54. |