Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Jin: И снова о наследовании (https://javascript.ru/forum/project/40210-jin-i-snova-o-nasledovanii.html)

nerv_ 29.07.2013 11:10

Цитата:

Сообщение от tenshi
Более существенные замечания будут?)

где точки с запятой? :)

tenshi 29.07.2013 11:20

Они-то зачем?

MODist 29.07.2013 15:46

Можно увидеть еще пару примеров? Хочется оценить читабельность и ясность синтаксиса библиотеки. Какой-нибудь характерный пример, где есть наследование, переопределение методов, примешивание. Скажем:

Disposable (примесь)
+ destroy
+ isDestroyed()

Observable (примесь)
+ events []
+ addEvent(eventName, callback, scope)
+ removeEvent(eventName, callback, scope)

Widget () (сюда примешиваем Disposable, Observable)
+ targetDomEL null
+ isRendered()
+ render(targetDomEl)
+ hide()
+ show()

ModalWindow-(наследуется от)->Widget
- title string
- titleDomEl
- contentDomEl
+ isClosed()
+ close()
+ setTitle(title) (делаем валидацию, что это точно string или number)
+ setContent(html)

tenshi 30.07.2013 11:00

Примерно так:

// Destroyable.js - поведение удаляемых объектов

$jin.property( 'Destroyable__destroyed', function Destroyable__destroyed( state ){
    if( !arguments.length ) return false
    
    if( state && !this.destroyed() ) this.proceedDestroy()
    
    return Boolean( state )
})

$jin.method( function Destroyable__proceedDestroy( ){ } )

// Спокойно примешиваем ко всем классам, потому что поведение это нужно всем, а тупые разработчики фреймворка этого не предусмотрели
$jin.mixin( 'Destroyable', '$jin_klass' )


// Renderable.js - поведение объектов, которые умеют рендерить себя в хтмл-элемент

$jin.property( 'Renderable__element', null )
$jin.method( function Renderale__rendered( state ){
    if( !arguments.length ) return Boolean( this.element() )
    
    state = Boolean( state )
    var rendered = this.rendered()
    if( state === rendered ) return this
    
    if( rendered ) this.proceedDeRender()
    else this.proceedRender()
    
    return this
})


// Observable.js - поведение объектов, на события которых можно подписываться

$jin.property( 'Observable__mapping', Object )

$jin.method( function Observable__listen( eventName, handler ){
    var mapping = this.mapping()
    var handlerList = mapping[ eventName ] = mapping[ eventName ] || []
    
    if( !~handlerList.indexOf( handler ) ) handlerList.push( handler )
    
    return { destroy: function( ){
        handlerList.splice( handlerList.indexOf( handler ), 1 )
    } }
} )

$jin.method( function Observable__scream( event ){
    var handlers = this.mapping()[ event.name ] || []
    handlers.forEach( function( handler ){
        handler( event )
    })
    return this
})


// Widget.js - класс с базовым поведением виджета

$jin.klass( 'Observable', 'Renderable', 'Widget' )
$jin.property( 'Widget__elementClass', String )

$jin.method( function Widget__visible( state ){
    if( !arguments.length ){
        return this.element().style.display !== 'none'
    }
    
    this.element().style.display = state ? '' : 'none'
} )

$jin.method( function Widget__proceedRender( ){
    var element = document.createElement( 'div' )
    element.className = this.elementClass()
    document.body.appendChild( element )
    
    this
    .element( element )
    .scream({ name: 'rendered' })
    
    return this
})

$jin.method( function Widget__proceedDeRender( ){
    var element = this.element()
    element.parentNode.removeChild( element )
    
    this
    .element( null )
    .scream({ name: 'derendered' })
    
    return this
})

$jin.method( 'Destroyable__proceedDestroy', function Widget__proceedDestroy( ){
    return this.rendered( false )
})


// ModalWindow.js - конкретный полностью работоспособный виджет

$jin_klass( 'Widget', 'ModalWindow' )

$jin.property( 'Widget__elementClass', 'ModalWindow__elementClass',
function( value ){
    return String( value || 'popup' )
} )

$jin.property( 'ModalWindow__title', String )
$jin.property( 'ModalWindow__titleClass', function( value ){
    return String( value || 'popup-title' )
} )

$jin.property( 'ModalWindow__content', String )
$jin.property( 'ModalWindow__contentClass', function( value ){
    return String( value || 'popup-content' )
} )

$jin.method( function ModalWindow__proceedRender( ){
    this.Widget__proceedRender()
    var element = this.element()
    
    var title = document.createElement( 'div' )
    title.className = this.titleClass()
    title.innerText = this.text()
    element.appendChild( title )
    
    var content = document.createElement( 'div' )
    content.className = this.contentClass()
    content.innerText = this.content()
    element.appendChild( content )
    
    return this
})

ModalWindow()
.elementClass( 'introduction-popup' )
.title( 'Intruduction' )
.content( '<iframe src="//youtu.be/xAHJIyfUSwU"></iframe>' )
.rendered( true )

monolithed 08.08.2013 18:52

Цитата:

Сообщение от nerv_
вЯваСкриптеCamelCase

Стараюсь никода не использовать CamelCase (разве что для функций-конструкторов)

nerv_ 18.08.2013 14:03

Цитата:

Сообщение от monolithed
Стараюсь никода не использовать CamelCase (разве что для функций-конструкторов)

почему? Я придерживаюсь мнения, что надо писать в "едином ключе/стиле", который задан окружением (браузером) и самим языком (Array.indexOf).

tenshi 19.08.2013 20:30

А мне как-то пофиг. Не стоит предавать слишком большое значение оформлению. Лучше над содержанием подумайте.


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