A DSL Context resolve duas situações nos projetos com o Beagle:
Ao iniciar um contexto, você popula um mapa com chave/valor e esse valor é um objeto qualquer (Any)
e para serem alterados, você precisa utilizar o método SetContext()
, veja abaixo:
context = ContextData("myBoolean", false),
onInit = listOf(
SetContext(
contextId = "myBoolean",
value = true
)
## **Como funciona a DSL Context?**
A DSL Context funciona por meio de um processador de anotações, onde são geradas extensões das classes de contexto que são anotadas com **@ContextObject** e para cada propriedade são criadas 2 extensões:
- **`expression`**: Usada para resgatar um **Bind.Expression** contendo o seu valor.
- **`change`**: Usada para alterar o valor dessa propriedade.
```kotlin
// extensões geradas
public val MyContext.valueExpression: Bind.Expression<String>
get() = expressionOf("@{$id.value}")
public fun MyContext.changeValue(value: String): SetContext {
val contextIdSplit = splitContextId(id)
return SetContext(
contextId = contextIdSplit.first,
path = "${if (contextIdSplit.second != null) "${contextIdSplit.second}." else ""}value",
value = value
)
}
Utilize a anotação @ContextObject em data classes que você deseja atribuir como contexto e, obrigatoriamente, elas devem implementar uma interface chamada Context
que possui uma marcação ID.
Todos os subtipos que o contexto possui devem ser anotados. Veja abaixo:
@ContextObject
data class MyContext(
override val id: String,
val value: String = "",
val person: Person = Person("")
) : Context
As extensões expression
e change
foram geradas para as propriedades value e person no arquivo chamado MyContextNormalizer, veja abaixo:
public val MyContext.valueExpression: Bind.Expression<String>
get() = expressionOf("@{$id.value}")
public fun MyContext.changeValue(value: String): SetContext {
val contextIdSplit = splitContextId(id)
return SetContext(
contextId = contextIdSplit.first,
path = "${if (contextIdSplit.second != null) "${contextIdSplit.second}." else ""}value",
value = value
)
}
public fun MyContext.changeValue(value: Bind.Expression<String>): SetContext {
val contextIdSplit = splitContextId(id)
return SetContext(
contextId = contextIdSplit.first,
path = "${if (contextIdSplit.second != null) "${contextIdSplit.second}." else ""}value",
value = value
)
}
public val MyContext.personExpression: Bind.Expression<Person>
get() = expressionOf("@{$id.person}")
public fun MyContext.changePerson(person: Person): SetContext {
val contextIdSplit = splitContextId(id)
return SetContext(
contextId = contextIdSplit.first,
path = "${if (contextIdSplit.second != null) "${contextIdSplit.second}." else ""}person",
value = person
)
}
public fun MyContext.changePerson(person: Bind.Expression<Person>): SetContext {
val contextIdSplit = splitContextId(id)
return SetContext(
contextId = contextIdSplit.first,
path = "${if (contextIdSplit.second != null) "${contextIdSplit.second}." else ""}person",
value = person
)
}
Para você inicializar um Contexto Local, crie uma instância do data class
e é necessário atribuir um contexto de algum componente:
private var myContext = MyContext("myContext",
person = Person(
id = "person",
firstName = "firstName local",
lastName = "lastName local")
)
Container(context = myContext)
Se você acessar a expressão de uma determinada propriedade, utilize a extensão expression:
Text(myContext.valueExpression),
Text(myContext.person.firstNameExpression),
Text(myContext.person.lastNameExpression)
Caso deseje alterar o valor de uma das propriedades, utilize a extensão change:
myContext.person.changeFirstName("new first name")
myContext.changeValue("new value")
Para você criar um contexto global, crie um data class
anotado com @GlobalContext:
@GlobalContext
data class GlobalObject(
val street: String = "",
val person: Person = Person("")
)
data classes
devem ser var e possuir um valor default.As extensões são criadas para cada propriedade do seu contexto global, assim você consegue acessá-las e depois alterar seus valores.
data class
anotada com @GlobalContextPara você utilizar o contexto global, inicie uma nova instância da data class
anotada com o @GlobalContext. Por meio das extensões, você pode acesssar/alterar os valores deste contexto, veja como:
var globalObject = GlobalObject()
globalObject.change(
GlobalObject("Street A",
Person("", "first name global", "last name global"))),
globalObject.person.change(Person("", "firstName global changed", "lastName global changed"))
O Contexto implícito através de um lambda
recebe um objeto definido como parâmetro, isso é para você acessar os possíveis valores que ele recebe e manipular/atributir a outros contextos.
Para você declarar um contexto implícito:
@RegisterWidget
class Input(
val hint: Bind<String>,
@ImplicitContext
val onTextChange: List<Action>? = null
) : Widget()
//gerado
public fun input(hint: Bind<String>, onTextChange: ((java.lang.String) -> List<Action>)? = null):
Input = Input(hint, onTextChange?.invoke(java.lang.String("onTextChange")))
Se você quiser usar esse Widget com o contexto implícito, você deve chamar a função abaixo:
input(
hint = valueOf(""),
onTextChange = {
listOf(
myContext.changeValue(expressionOf("@{${it}}"))
)
}
)
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.