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, время: 02:17. |