Данная библиотека является идеей, и носит демонстрационный характер.

class For

import { For } from "bakugan";
Класс предоставляющий работу с множеством данных. Унаследован от класса Component
Создание
new For(name: { name: string }, props: IHashMapAny);
new For(name: string, props: IHashMapAny);
new For(props: IHashMapAny);
Создает экземпляр класса For
подробней
Параметры:
  • name: string | { name: string } - задает имя компоненту. Если имя не указано, то оно будет присвоено автоматически
  • props: IHashMapAny - параметры. Можно передавать любые параметры, но данный класс имеет следующие зарезервированные параметры (плюс параметры класса Component, т.к. он является его наследником):
    1. items: IHashMapAny[] - массив параметров для каждого элемента
    2. template: Template | string - дочерний шаблон (переопределен)
    3. ctor: BaseComponent | string - использовать конструктор класса для элемента
    4. wrapCtor: boolean - использовать обертку Tmp. Данный флаг будет работать если задан параметр ctor
import { Component, For, Template, template } from "bakugan";

@template({
    html: `
        <div>
            <ul ref="ul">
                <for ref="myFor" items="cloneData()">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }];
    }

    public cloneData(): any[] {
        return this.data.map((item: any) => item);
    }
}

const app: App = new App();
app.bindTo(document.body);

const newFor: For = new For({ name: "newFor" }, {
    items: app.cloneData(),

    context: app,
    template: Template.make({
        html: `
            <div>
                <span style="background-color: red;">
                    <span>-</span>
                    <txt html="props.item.text"></txt>
                </span>
            </div>
        `,
    }),
});

app.get("ul").insertAfter(newFor);
смотреть пример: web | github
Методы
getAt(index: number, inversion?: boolean): BaseComponent
Получает компонент по индексу
подробней
Параметры:
  • index: number - индекс получаемого компонента
  • inversion?: boolean - отсчет с другого конца
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");
const item: Tmp = myFor.getAt(2);

console.log(item); // Tmp
console.log(item.props.item.text); // third
смотреть пример: web | github
push(...args: IHashMapAny[]): void
Добавляет компоненты в конец
подробней
Параметры:
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

// ------------------------------------------

function pop(): void {
    myFor.pop(2);
}

function push(): void {
    myFor.push({ text: `insert after 1` }, { text: `insert after 2` });
}

function shift(): void {
    myFor.shift(2);
}

function unshift(): void {
    myFor.unshift({ text: `insert before 1` }, { text: `insert before 2` });
}

function splice(): void {
    myFor.splice(1, 3, [{ text: `insert center` }]);
}

// ------------------------------------------

const actions = [pop, push, shift, unshift, splice];

let index: number = 0;
function run() {
    setTimeout(() => {
        const action = actions[index++];

        action();

        if (actions.length > index) {
            run();
        }
    }, 2000);
}

run();
смотреть пример: web | github
pop(count: number = 1): void
Удаляет компоненты с конца
подробней
Параметры:
  • count: number = 1 - количество удаляемых компонентов (по умолчанию 1)
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

// ------------------------------------------

function pop(): void {
    myFor.pop(2);
}

function push(): void {
    myFor.push({ text: `insert after 1` }, { text: `insert after 2` });
}

function shift(): void {
    myFor.shift(2);
}

function unshift(): void {
    myFor.unshift({ text: `insert before 1` }, { text: `insert before 2` });
}

function splice(): void {
    myFor.splice(1, 3, [{ text: `insert center` }]);
}

// ------------------------------------------

const actions = [pop, push, shift, unshift, splice];

let index: number = 0;
function run() {
    setTimeout(() => {
        const action = actions[index++];

        action();

        if (actions.length > index) {
            run();
        }
    }, 2000);
}

run();
смотреть пример: web | github
unshift(...args: IHashMapAny[]): void
Добавляет компоненты в начало
подробней
Параметры:
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

// ------------------------------------------

function pop(): void {
    myFor.pop(2);
}

function push(): void {
    myFor.push({ text: `insert after 1` }, { text: `insert after 2` });
}

function shift(): void {
    myFor.shift(2);
}

function unshift(): void {
    myFor.unshift({ text: `insert before 1` }, { text: `insert before 2` });
}

function splice(): void {
    myFor.splice(1, 3, [{ text: `insert center` }]);
}

// ------------------------------------------

const actions = [pop, push, shift, unshift, splice];

let index: number = 0;
function run() {
    setTimeout(() => {
        const action = actions[index++];

        action();

        if (actions.length > index) {
            run();
        }
    }, 2000);
}

run();
смотреть пример: web | github
shift(count: number = 1): void
Удаляет компоненты с начала
подробней
Параметры:
  • count: number = 1 - количество удаляемых компонентов (по умолчанию 1)
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

// ------------------------------------------

function pop(): void {
    myFor.pop(2);
}

function push(): void {
    myFor.push({ text: `insert after 1` }, { text: `insert after 2` });
}

function shift(): void {
    myFor.shift(2);
}

function unshift(): void {
    myFor.unshift({ text: `insert before 1` }, { text: `insert before 2` });
}

function splice(): void {
    myFor.splice(1, 3, [{ text: `insert center` }]);
}

// ------------------------------------------

const actions = [pop, push, shift, unshift, splice];

let index: number = 0;
function run() {
    setTimeout(() => {
        const action = actions[index++];

        action();

        if (actions.length > index) {
            run();
        }
    }, 2000);
}

run();
смотреть пример: web | github
splice(start: number, count: number, add: IHashMapAny[]): void
Изменяет компоненты
подробней
Параметры:
  • start: number - индекс, с которого будут изменяться компоненты
  • count: number - количество удаляемых компонентов
  • add: IHashMapAny[] - список параметров для новых компонентов
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

// ------------------------------------------

function pop(): void {
    myFor.pop(2);
}

function push(): void {
    myFor.push({ text: `insert after 1` }, { text: `insert after 2` });
}

function shift(): void {
    myFor.shift(2);
}

function unshift(): void {
    myFor.unshift({ text: `insert before 1` }, { text: `insert before 2` });
}

function splice(): void {
    myFor.splice(1, 3, [{ text: `insert center` }]);
}

// ------------------------------------------

const actions = [pop, push, shift, unshift, splice];

let index: number = 0;
function run() {
    setTimeout(() => {
        const action = actions[index++];

        action();

        if (actions.length > index) {
            run();
        }
    }, 2000);
}

run();
смотреть пример: web | github
sort(fn: (comp1: BaseComponent, comp2: BaseComponent) => any): void
Сортирует список компонентов
подробней
Параметры:
  • fn: (comp1: BaseComponent, comp2: BaseComponent) => any - функция, по которой будет происходить сортировка
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

myFor.sort((tmp1: Tmp, tmp2: Tmp) => {
    return tmp1.props.item.text < tmp2.props.item.text ? -1 : 1;
});
смотреть пример: web | github
load(data: IHashMapAny[], fn: (props: IHashMapAny) => any, callback?: (component: BaseComponent, newProps: IHashMapAny) => void): void
Загружает новый список компонентов по ключу
подробней
Параметры:
  • data: IHashMapAny[] - список параметров для новых компонентов
  • fn: (props: IHashMapAny) => any - функция, возвращающая ключ
  • callback?: (component: BaseComponent, newProps: IHashMapAny) => void): void - функция для обновления
import { Component, For, Tmp, template } from "bakugan";

interface IItem {
    key: number;
    text: string;
}

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt ref="text" html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: IItem[];

    public beforeInit(component: App): void {
        this.data = [{
            key: 1,
            text: `first`,
        }, {
            key: 2,
            text: `second`,
        }, {
            key: 3,
            text: `third`,
        }, {
            key: 4,
            text: `fourth`,
        }, {
            key: 5,
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

const newData: IItem[] = [{
    key: 2,
    text: ` - second`,
}, {
    key: 5,
    text: ` - fifth`,
}, {
    key: 7,
    text: ` - seventh`,
}];

myFor.load(newData, (props: IItem) => props.key, (tmp: Tmp, newProps: IItem) => {
    console.log("callback to update");
    console.log(tmp);

    setTimeout(() => {
        tmp.html({ text: newProps.text });
    }, 1000);
});
смотреть пример: web | github
clean(): void
Очищает список компонентов
подробней
import { Component, For, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");
myFor.clean();

console.log(myFor.count()); // 0
смотреть пример: web | github
forEach(callback: (component: BaseComponent) => void): void
Перебирает все компоненты
подробней
Параметры:
  • callback: (component: BaseComponent) => void - функция, вызывающаяся для каждого компонента
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

myFor.forEach((tmp: Tmp) => {
    console.log(tmp);
});
смотреть пример: web | github
filter(callback: (component: BaseComponent) => boolean): BaseComponent[]
Возвращает отфильтрованный список компонентов
подробней
Параметры:
  • callback: (component: BaseComponent) => boolean - функция, по которой будет происходить фильтрация
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

const list: Tmp[] = myFor.filter((tmp: Tmp) => {
    return tmp.props.item.text.charAt(0) === "f";
}) as any;

console.log(list);
смотреть пример: web | github
getItems(): BaseComponent[]
Возвращает весь список компонентов
подробней
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

console.log(myFor.getItems());
смотреть пример: web | github
count(): number
Возвращает количество элементов
подробней
import { Component, For, Tmp, template } from "bakugan";

@template({
    html: `
        <div>
            <ul>
                <for ref="myFor" items="data">
                    <li>
                        <txt html="props.item.text"></txt>
                    </li>
                </for>
            </ul>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public beforeInit(component: App): void {
        this.data = [{
            text: `first`,
        }, {
            text: `second`,
        }, {
            text: `third`,
        }, {
            text: `fourth`,
        }, {
            text: `fifth`,
        }];
    }
}

const app: App = new App();
app.bindTo(document.body);

const myFor: For = app.get("myFor");

console.log(myFor.count());
смотреть пример: web | github
ctor(ctor: ICtorBaseComponent, tmp?: Template, wrapCtor?: boolean): void
ctor(ctor: string, tmp?: Template, wrapCtor?: boolean): void
ctor(ctor: ICtorBaseComponent, tmp?: string, wrapCtor?: boolean): void
ctor(ctor: string, tmp?: string, wrapCtor?: boolean): void
Меняет конструктор класса для элемента
подробней
Параметры:
  • ctor: ICtorBaseComponent | string - класс для дочернего элемента. Если указан string, то класс будет браться из параметра
  • tmp?: Template | string - дочерний шаблон. Если указан string, то шаблон будет браться из параметра
  • wrapCtor?: boolean - использовать обертку Tmp
import { Component, Native, For, Tmp, Template, template } from "bakugan";

// component ItemOne

@template({
    html: `
        <div>
            <span>
                <txt ref="index" html="parent().index()"></txt>-
            </span>
            <span>
                <txt ref="myTxt" html="props.item.text"></txt>
            </span>
        </div>
    `,
})
class ItemOne extends Component {
    public beforeInit(): void {
        console.log(this.props);
    }
}

// component ItemTwo

@template({
    html: `
        <div>
            <span style="font-weight: bold;">
                <txt ref="myTxt" html="props.item.text"></txt>
            </span>
            <tmp ref="myTmp" template="props.template"></tmp>
        </div>
    `,
})
class ItemTwo extends Component { }

// template

const tmp: Template = Template.make({
    html: `
        <span style="cursor: pointer; margin-left: 10px;">[x]</span>
    `,
});

// component app

@template({
    html: `
        <div>
            <div style="margin-bottom: 20px;">
                <input type="button" value="set ItemOne" onClick="setItemOne" />
                <input type="button" value="set ItemTwo" onClick="setItemTwo" />
                <input type="button" value="set dynamic" onClick="setDynamic" />
                <input type="button" value="use wrap tmp" onClick="useWrap" ref="useWrap" />
                <input type="button" value="reset" onClick="reset" />
            </div>
            <for ref="myFor" items="data">
                <div>
                    <txt ref="myTxt" html="props.item.text"></txt>
                </div>
            </for>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public wrap: boolean = false;

    public base: any;

    public beforeInit(): void {
        this.data = [{
            text: `first`,
            item: ItemOne,
        }, {
            text: `second`,
            item: ItemTwo,
        }, {
            text: `third`,
            item: ItemOne,
        }];
    }

    public afterInit(): void {
        this.base = this.get("myFor").tmp();
    }

    public setItemOne(): void {
        const myFor: For = this.get("myFor");

        myFor.ctor(ItemOne, null, this.wrap);
    }

    public setItemTwo(): void {
        const myFor: For = this.get("myFor");

        myFor.ctor(ItemTwo, tmp, this.wrap);
    }

    public setDynamic(): void {
        const myFor: For = this.get("myFor");

        myFor.ctor("item", tmp, this.wrap);
    }

    public useWrap(): void {
        this.wrap = !this.wrap;

        const myFor: For = this.get("myFor");
        const useWrap: Native = this.get("useWrap");

        const background: any = {};
        if (this.wrap) {
            background.backgroundColor = "green";
        }

        useWrap.css(background, true);

        myFor.wrapCtor(this.wrap);
    }

    public reset(): void {
        const myFor: For = this.get("myFor");

        myFor.tmp(this.base);
    }
}

const app: App = new App();
app.bindTo(document.body);
смотреть пример: web | github
wrapCtor(wrapCtor: boolean): void
Использовать обертку Tmp. Обертку можно включать только если задан конструктор
подробней
Параметры:
  • wrapCtor: boolean - флаг, указывающий использовать Tmp или нет
import { Component, Native, For, Tmp, Template, template } from "bakugan";

// component ItemOne

@template({
    html: `
        <div>
            <span>
                <txt ref="index" html="parent().index()"></txt>-
            </span>
            <span>
                <txt ref="myTxt" html="props.item.text"></txt>
            </span>
        </div>
    `,
})
class ItemOne extends Component {
    public beforeInit(): void {
        console.log(this.props);
    }
}

// component ItemTwo

@template({
    html: `
        <div>
            <span style="font-weight: bold;">
                <txt ref="myTxt" html="props.item.text"></txt>
            </span>
            <tmp ref="myTmp" template="props.template"></tmp>
        </div>
    `,
})
class ItemTwo extends Component { }

// template

const tmp: Template = Template.make({
    html: `
        <span style="cursor: pointer; margin-left: 10px;">[x]</span>
    `,
});

// component app

@template({
    html: `
        <div>
            <div style="margin-bottom: 20px;">
                <input type="button" value="set ItemOne" onClick="setItemOne" />
                <input type="button" value="set ItemTwo" onClick="setItemTwo" />
                <input type="button" value="set dynamic" onClick="setDynamic" />
                <input type="button" value="use wrap tmp" onClick="useWrap" ref="useWrap" />
                <input type="button" value="reset" onClick="reset" />
            </div>
            <for ref="myFor" items="data">
                <div>
                    <txt ref="myTxt" html="props.item.text"></txt>
                </div>
            </for>
        </div>
    `,
})
class App extends Component {

    public data: any[];

    public wrap: boolean = false;

    public base: any;

    public beforeInit(): void {
        this.data = [{
            text: `first`,
            item: ItemOne,
        }, {
            text: `second`,
            item: ItemTwo,
        }, {
            text: `third`,
            item: ItemOne,
        }];
    }

    public afterInit(): void {
        this.base = this.get("myFor").tmp();
    }

    public setItemOne(): void {
        const myFor: For = this.get("myFor");

        myFor.ctor(ItemOne, null, this.wrap);
    }

    public setItemTwo(): void {
        const myFor: For = this.get("myFor");

        myFor.ctor(ItemTwo, tmp, this.wrap);
    }

    public setDynamic(): void {
        const myFor: For = this.get("myFor");

        myFor.ctor("item", tmp, this.wrap);
    }

    public useWrap(): void {
        this.wrap = !this.wrap;

        const myFor: For = this.get("myFor");
        const useWrap: Native = this.get("useWrap");

        const background: any = {};
        if (this.wrap) {
            background.backgroundColor = "green";
        }

        useWrap.css(background, true);

        myFor.wrapCtor(this.wrap);
    }

    public reset(): void {
        const myFor: For = this.get("myFor");

        myFor.tmp(this.base);
    }
}

const app: App = new App();
app.bindTo(document.body);
смотреть пример: web | github