Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Конструктор для компонента (https://javascript.ru/forum/misc/37056-konstruktor-dlya-komponenta.html)

Дюрі-бачі 06.04.2013 08:06

Конструктор для компонента
 
Необходимо создать DOM-елемент с некоторыми дополнениями. Сейчас использую такую конструкцию:
function Menu(options){
	var  self = document.createElement('div'),
	_items=options.items || [],
	_itemsCount=options.itemsCount || _items.length;
        // другие свойства ...
	function construct(){
		var it = document.createElement('ul');
		it.className = 'Menu';
		for (var i=0;i<_itemsCount;i++){
			var item=document.createElement('li');
			item.innerHTML = '<p class="MenuItemTitle">'+ _items[i]+'</p>';
			// формируем подменю...
			it.appendChild(item);
		}; //item
		self.appendChild(it); 
	}; //construct
	construct();
	return self;
};// Menu

Надо переписать фабричную функцию в конструктор: чтоб вместо self использовалось this, а наследование шло через прототипы.
:help: Помогите пожайлуста:
Menu.prototype = document.createElement('div');   //наследуем от Div
function Menu(options){
	var  self = this,
	_items=options.items || [],
	_itemsCount=options.itemsCount || _items.length;
        // другие свойства ...
	function construct(){
		var it = document.createElement('ul');
					// формируем подменю...
		self.appendChild(it); // ОШИБКА!!! Uncaught TypeError: Illegal invocation
	}; //construct
	construct();
};// Menu

как исправить ошибку?

megaupload 08.04.2013 16:51

я вообще вопроса не понял даже не то что кода

Дюрі-бачі 08.04.2013 21:27

Код должен создавать компонент, припустим Меню и быть полноценным объектом. Сейчас я его создаю при помощи фабричной функции (первый код, возвращает полноценный node внутри которого есть меню, можно потом вставить в DOM структуру документа, или сделать JQuery обёртку вокруг него...), но при таком подходе есть проблемы с наследованием, надо переделать чтоб создавалось через конструктор, но у меня не получается.

zebra 08.04.2013 21:33

Даже не взирая на ошибки в коде, хочу спросить - в классе Menu на что будет ссылаться this?

dmitriymar 08.04.2013 21:35

Цитата:

Сообщение от Дюрі-бачі
self.appendChild(it); // ОШИБКА!!! Uncaught TypeError: Illegal invocation

в первую очередь ответьте, для себя, на вопросы:
на что ссылается this в конструкторе , в объекте?
во что можно можно вставлять будущий элемент Dom дерева?

Все ответы есть в учебнике http://learn.javascript.ru/
P.S что за манера в последнее время , написав ерунду и не получив на неё ответа, не искать ошибки и решения ,а апать со словами : Эчто никто не знает" и т.д?

megaupload 08.04.2013 21:46

var __extends = this.__extends || function (d, b) {
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};

var Animal = (function () {
    function Animal() { }
    Animal.prototype.say = function () {
        alert('animal');
    };
    return Animal;
})();

var Cat = (function (_super) {
    __extends(Cat, _super);
    function Cat() {
        _super.apply(this, arguments);

    }
    Cat.prototype.say = function () {
        _super.prototype.say.call(this);
        alert('cat');
    };
    return Cat;
})(Animal);

new Cat().say()


дает ли тебе этот код что нибудь?

Дюрі-бачі 08.04.2013 21:59

Цитата:

Сообщение от zebra
Даже не взирая на ошибки в коде, хочу спросить - в классе Menu на что будет ссылаться this?

По идее должен на пустой обьект, прототипом которого есть DIV, соответственно из него должен наследовать childNodes и appendChild. После исполнения конструктора должен быть node со своими методами и свойствами, который потом можно добавить в документ.
megaupload, Ну читал я учебник это работает когда объекты обычные, а вот DOM не работает, или я не понимаю как оно должно работать.
Цитата:

Сообщение от dmitriymar
P.S что за манера в последнее время , написав ерунду и не получив на неё ответа, не искать ошибки и решения ,а апать со словами : Эчто никто не знает" и т.д?

Извиняюсь, если б я знал как исправить - то исправил бы. Уже пробовал по разному и первый пост редактировал несколько раз соответственно, но не работает ни один из вариантов, например
this = document.createElement('div'),

zebra 08.04.2013 22:18

function Menu(opt) {
    this.el = document.createElement('div'); // или лучше document.createDocumentFragment()
    this.construct(opt);
}
Menu.prototype.construct = function() {
     // this.el.append(список)
};
//body.appendChild(new Menu().el)

Лучше как-то так реализуйте

Дюрі-бачі 08.04.2013 22:52

zebra,Спасибо, конечно криво возвращать элемент через свойство, но зато хоть рабочий вариант. Теперь даже не знаю стоит ли переделывать весь код.

P.S. С JS раньше дела не имел, и хотелось как в обычных языках: делаем потомка класса стандартного компонента, дополняем его на свое усмотрение, создаем конкретные экземпляры, а здесь, вижу все абсолютно по другому...

Дюрі-бачі 09.04.2013 00:40

Цитата:

В стандарте the Option Element есть любопытный короткий синтаксис для создания элемента с тегом option:
option = new Option( text, value, defaultSelected, selected);
Вот такого и я хочу достичь.

zebra 09.04.2013 01:21

Menu.prototype = document.createElement('div'); - что именно здесь наследуется вы понимаете?
function M() {
   this.el = document.createElement('div');
   return this.getEl();
}
M.prototype.getEl = function() {
 return this.el;
};

megaupload 09.04.2013 01:28

он не отличает копирование от делегирования.

Aetae 09.04.2013 01:38

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

function Menu(options){
	function liToString(){
		return this.innerText || this.textContent;
	}

	var	d = document, 
		_ul = document.createElement('ul'),
		_items = options.items || [],
		_itemsCount = options.itemsCount || _items.length;
		
	;
	for(var i = 0; i<_itemsCount; i++){
		_ul[i] = _ul.appendChild(d.createElement('li'));
		_ul[i].appendChild(d.createTextNode(_items[i] || 'default'));
		_ul[i].toString = liToString;
	}
	_ul.length = _itemsCount;
    return _ul
};

var menu = new Menu({ //new тут никакой роли не играет =\
	items : ['1','два',3],
	itemsCount : 10
})

document.body.appendChild(menu)
alert([
	menu,
	menu[1],
	menu.length
].join('\n'))


P.S. С новомодным Proxy кстати можно такое творить... будет через годик другой.

danik.js 09.04.2013 06:29

Цитата:

Сообщение от Aetae
С новомодным Proxy кстати можно такое творить...

Например?


Часовой пояс GMT +3, время: 12:02.