https://kotlinlang.org logo
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
benchmarks
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
confetti
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
lincheck
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by
Title
i

irus

11/03/2017, 12:31 PM
val tree = root(
    div(classes = "main", render = h(
        users()
    )),
    users(),
    p("Test")
)

fun users() = ex {
    users.map {
        p(it.name)
    }
}

fun list() = e {
    ul(render = h(
        li("First"),
        li("Second")
    ))
}
s

snrostov

11/03/2017, 12:44 PM
Это чем то отличается от
Section(
      key = "s1",
      title = "About",
      children = listOf(
        Text("About contents")
      )
    )
?
i

irus

11/03/2017, 12:45 PM
В конечном итоге - нет
Какие проблемы с этим подходом?
s

snrostov

11/03/2017, 12:46 PM
все if, for и прочую логику нужно заменять на map, filter и т.д. Т.е. исключительно функциональный подход
можно добавить лямбду elements { yeild(element) }
но это как раз тоже самое что +
в роли плюса выступает yeild
i

irus

11/03/2017, 12:48 PM
val tree = root(
    div(classes = "main", render = h(
        e {
            if (condition) {
                users()
            } else {
                list()
            }
        }
    )),
    users(),
    p("Test")
)
s

snrostov

11/03/2017, 12:48 PM
только один элемент можно вернуть?
i

irus

11/03/2017, 12:48 PM
e - один елемент ex - лист
s

snrostov

11/03/2017, 12:48 PM
а если нужно в цикле что то понадобовлять и отфильтровать?
в случае ex - все равно функциональный подход?
например как написать вот это: for (user in users) { if (user.visible) { +user } }
i

irus

11/03/2017, 12:51 PM
ну конкретно этот пример прям просится функционально написать
s

snrostov

11/03/2017, 12:52 PM
да, все можно переписать в функциональный вид, но не все привыкли так писать. все привыкли писать процедурно
но вобще идея двух режимов интересная
можно сделать оба вида dsl, с функциональным подходом, и с некой функцией elements {} внутри которой использовать yeild (+)
i

irus

11/03/2017, 12:53 PM
val tree = root(
    div(classes = "main", render = h(
        ex {
            val render = mutableListOf<VDom>()

            for (user in users) {
                if (user.visible) {
                    render += p(user.name)
                }
            }

            render.toList()
        }
    )),
    users(),
    p("Test")
)
если хочется циклы, но абсолютно бесполезно
да, поверх этого можно прикрутить такой DSL с (+)
s

snrostov

11/03/2017, 12:55 PM
твое предолжение - это flutter. я пробовал так писать, очень сложно переключится с процедурного на функциональный
все таки все привыкли к процедурному подходу
но, с другой стороны функциональный подход открывает новые горизонты по реактивному рендеру
i

irus

11/03/2017, 12:56 PM
я привык к JSX - там как раз таки в основном функциональный подход
s

snrostov

11/03/2017, 12:56 PM
например если изменился один элемент списка, то будет рендерится только он. в процедурном такое не получить
я привык к JSX - там как раз таки в основном функциональный подход
а вот и нет 🙂 все примеры на сайте реакта как раз и продауют его как процедурный
а, нет вру
еще одна проблема с заданием дочерних элементов в виде списка - его, как ни крути, сложнее читать
i

irus

11/03/2017, 1:02 PM
const CandidatesViewComponent = ({candidates}: StateProps) => {
  return (
    <div className="container">
      <div className="row">
        {candidates.map((candidate: OsCandidateWithPerson) =>
          <div className="col-md-4"
               style={styles.candidate}
               key={candidate.id}>
            <Card>
              <CardHeader
                title={`${candidate.firstName} ${candidate.lastName}`}
                subtitle={`Status: ${candidate.status}`}
              />
              <CardText>
                Rating: {candidate.rating}
              </CardText>
              <CardActions>
                <Link to={`/candidates/${candidate.id}/view`}>
                  <FlatButton label="View Details"/>
                </Link>
              </CardActions>
            </Card>
          </div>
        )}
      </div>
    </div>
  );
};
s

snrostov

11/03/2017, 1:02 PM
из за того что скобки копятся очень быстро
i

irus

11/03/2017, 1:02 PM
вот типичный компонент на реакте
s

snrostov

11/03/2017, 1:02 PM
да, я ошибся про реакт. запутался
i

irus

11/03/2017, 1:03 PM
да, скобочки копятся. поэтому декомпозировать на функции
не пытаться описать все, как в примере выше
s

snrostov

11/03/2017, 1:14 PM
div(className = "container",
    children = [div(
        className = "row",
        children = candidates.map { condidate ->
            div(
                className = "col-md-4",
                children = [card(
                    children = [
                        cardHeader(
                            title = "${candidate.firstName} ${candidate.lastName}",
                            subtitle="Status: ${candidate.status}"
                        )
                        cardText(
                            children = ["Rating: ", candidate.rating]
                        )
                        cardActions(
                            children = link(
                                to = "/candidates/${candidate.id}/view",
                                children = [flatButton(label = "View Details")]
                            )
                        )
                    ]
                )
            )]
        )]
    )
очень сложно читать
и писать, наверное тоже...
div(className = "container") { div(className = "row") { candidates.forEach { condidate -> div(className="col-md-4") { card { cardHeader( title = "${candidate.firstName} ${candidate.lastName}", subtitle="Status: ${candidate.status}" ) cardText { +"Rating: " +candidate.rating } cardActions { link(to = "/candidates/${candidate.id}/view") { flatButton(label = "View Details") } } } } } } }
это то что в kotlinx.html
+Div(className = "container") { +Div(className = "row") { candidates.forEach { condidate -> +Div(className="col-md-4") { +Card { +CardHeader( title = "${candidate.firstName} ${candidate.lastName}", subtitle="Status: ${candidate.status}" ) +CardText { +"Rating: " +candidate.rating } +CardActions { +Link(to = "/candidates/${candidate.id}/view") { +FlatButton(label = "View Details") } } } } } } }
а это с плюсиками
кстате вот тут хорошо видно: в kotlinx.html forEach сложно разглядеть
не пытаться описать все, как в примере выше
ну вот проблема в том, что в kotlinx.html даже если все сразу описывать, все равно хорошо читается
было бы круто чтобы выглядело как в kotlinx.html но не требовалось бы объявлять билдеры дополнительно (и кучи кода для реакта)
i

irus

11/03/2017, 2:03 PM
А мне нравится:
fun candidatesViewComponent() = element {
    div(classes = "container", render = h(
        div(classes = "row", render = elements {
            candidates.map {
                div(classes = "col-md-4", style = "styles.candidate", render = h(
                    cardHeader(
                        title = "${it.firstName} ${it.lastName}",
                        subtitle = "Status: ${it.status}"
                    ),
                    cardText("Rating: ${it.rating}"),
                    cardActions(render = h(
                        link(to = "/candidates/${it.id}/view", render = h(
                            flatButton(label = "View Details")
                        ))
                    ))
                ))
            }
        })
    ))
}
Другое дело что в реальности все сложнее может стать
s

snrostov

11/03/2017, 2:33 PM
Идея так не умеет форматировать...
i

irus

11/03/2017, 2:37 PM
автореформат не сломал мне этот код
s

snrostov

11/03/2017, 2:39 PM
хм... мне он сделал такое:
fun candidatesViewComponent() = element {
  div(
      classes = "container", render = h(
      div(
          classes = "row", render = elements {
        candidates.map {
          div(
              classes = "col-md-4", style = "styles.candidate", render = h(
              cardHeader(
                  title = "${it.firstName} ${it.lastName}",
                  subtitle = "Status: ${it.status}"
              ),
              cardText("Rating: ${it.rating}"),
              cardActions(
                  render = h(
                      link(
                          to = "/candidates/${it.id}/view", render = h(
                          flatButton(label = "View Details")
                      )
                      )
                  )
              )
          )
          )
        }
      }
      )
  )
  )
}
i

irus

11/03/2017, 2:40 PM
Видимо у меня специальные настройки в code style
s

snrostov

11/03/2017, 2:40 PM
1.2 - rc
или у меня )
i

irus

11/03/2017, 2:47 PM
Ну я точно code style менял, чтобы отступы меньше были