Operações
Nesta seção, você encontra descrição completa das Operações.
Beagle v1.5 não é mais mantida ativamente. A versão documentada que você está visualizando pode conter funcionalidades depreciadas. Para obter as funcionalidades mais recentes, consulte a nossa última versão .
O contexto é uma variável de qualquer tipo, incluindo o mapa que define um conjunto de pares de chaves/valores. Por meio de bindings, o valor do contexto pode ser acessado por qualquer componente ou ação do seu escopo.
A tabela abaixo demonstra os principais atributos do contexto:
Atributo | Tipo | Obrigatoriedade | Definição |
---|---|---|---|
id | String | ✓ | Identificador do contexto |
value | Any | ✓ | Valor do contexto |
De modo geral, o contexto pode ser usado quando você quer preencher valores em um momento diferente daquele em que recebeu os componentes com o JSON.
No exemplo abaixo, você pode ver o contexto com dados de um usuário e sendo mostrados algumas dessas informações em um Text
:
Container(
context = ContextData(
id = "myData",
value = User(
id = "0000"
name = "User",
age = "18"
)
),
children = listOf(
Text("Name: @{myData.name}"),
Text("Age: @{myData.age}")
)
)
Perceba que o contexto foi declarado e seus valores foram definidos e usados para preencher os textos, porém é possível definir esses valores depois usando o método SetContext()
.
Dessa forma, você pode preencher os componentes com dados que ainda não estavam no JSON.
bindings
.Há duas formas para usar contexto: contexto explícito e implícito. A principal diferença entre eles é o escopo do contexto, que pode (ou não) ser definido dentro do JSON ou da estrutura declarativa que estiver usando.
O escopo de um contexto é o componente no qual seus descendentes são definidos. Isso torna possível acessar o contexto declarado em uma outra branch da árvore.
Um contexto pode ser estabelecido em qualquer componente do Beagle que implementa o ContextComponent
, que é a propriedade do context
que pode especificar os seguintes componentes:
Container
Screen
ScrollView
PageView
TabView
Custom Components
, que implementa o ContextComponent
Quando há um escopo definido para o contexto dentro do seu JSON ou da sua estrutura declarativa.
Veja o exemplo abaixo de como funciona:
Container(
context = ContextData(
id = "myData",
value = User(
id = "0000"
name = "User",
age = "18"
)
),
children = listOf(
Text("Name: @{myData.name}"),
Text("Age: @{myData.age}")
)
)
Perceba que o contexto foi declarado e seus valores foram definidos e usados para preencher os textos, porém é possível definir depois esses valores usando o método SetContext()
. Dessa forma, você pode preencher os componentes com dados que ainda não estavam no JSON.
Quando não há um escopo de contexto definido dentro do JSON ou da estrutura declarativa da sua tela, mas que podem ser acessados por bindings.
Isso significa que esse tipo de contexto é criado por meio de eventos.
Além disso, o escopo desse tipo de contexto é definido apenas por uma action ou um conjunto de ações relacionados ao evento criado no contexto.
Em alguns casos, é necessário acessar uma informação específica sobre um evento que engatilhou uma ação. Um exemplo comum é o onChange event
, que é lançado por qualquer componente e permite a entrada de dados.
Caso mude o valor de uma entrada de um componente e as ações a serem lançadas dependem desse valor, é fundamental que você tenha acesso ao novo valor do componente.
Outra característica do contexto implícito é que ele sempre possui um id
igual ao nome do evento criado. Se, por exemplo, o evento é o onCharge, o escopo do contexto terá id onChange
e binding ficará dessa forma:{ value: newValue },
no qual newValue
é o campo que você pode incluir um novo valor a ser usado.
Veja o exemplo abaixo com o evento onBlur
, que funciona exatamente como o onChange
, mas faz a requisição quando o input do componente perde o foco:
Screen(
child = Container(
children = listOf(
TextInput(
placeholder = "CEP",
onBlur = listOf(
Alert(
message = "example of implícit context: @{onBlur.value}"
)
)
)
)
)
)
Apesar do contexto onBlur
não ter sido declarado no exemplo acima, você consegue usá-lo porque ele foi criado de uma maneira implícita pelo evento onBlur
.
O que acontece é que o JSON define a view onde o foco se perdeu no campo de CEP e a ação é rodada para procurar o endereço com base no valor digitado. O resultado da requisição pode ser usado para definir o valor de outros campos no formulário de endereço.
Exemplos de eventos criados com contexto implícito:
onChange
onFocus
onBlur
onSuccess
onError
onFinish
Os três primeiros eventos são parte do contrato do componente beagle:textinput
enquanto os três últimos são parte da ação beagle:sendRequest
.
O binding é a string em um formato especial, que identifica o valor dentro de um contexto. Sem ele, não é possível criar contextos, sejam eles implícitos ou explícitos.
Durante o processo de renderização do Beagle, bindings podem ser substituídos pelos valores que são referenciados a ele.
Um binding é identificado com o prefixo**@{
** e o sufixo **}
**. Isso significa que tudo entre esses símbolos serve como uma expressão do contexto, que deve ser substituído quando você renderizar a tela.
Veja o exemplo abaixo de como funciona:
Container(
(children = listOf(Text("@{myText}"))),
(context = ContextData((id = "myText"), (value = "Hello Beagle")))
);
Para acessar o texto “Hello Beagle” por meio de bindings, é preciso especificar o id do contexto: @{myText}
.
No exemplo acima, o valor do contexto é uma simples string, mas você pode ver nos tópicos a seguir como acessar valores em contextos que são mapas ou arrays.
É o tipo de binding no qual o valor do contexto será, geralmente, uma chave/valor de um map (key/value map).
Nesses casos, os bindings devem ser usados para acessar subestruturas. Como acontece na maior parte de linguagens de programação, o Beagle usa pontos para fazer esse tipo de acesso, como você pode ver no exemplo abaixo:
@{user.cpf}
;@{user.phoneNumber.cellphone}
.No Kotlin é necessario que se crie algumas classes para gerenciar os contextos multivalorados
Container(
children = listOf(
Text("@{user.phoneNumber.cellphone}")
),
context = ContextData(
id = "user",
value = User(
cpf = "014.225.235-12",
phoneNumber = PhoneNumber(
cellphone = "(34) 98856-8563",
telephone = "(34) 3214-5588"
)
)
)
)
data class User(val cpf: String, val phoneNumber:PhoneNumber)
data class PhoneNumber(val cellphone:String, val telephone:String)
É o tipo de binding no qual o valor do contexto será, geralmente, vetores (arrays).
Se um vetor é usado no valor do contexto para acessar uma posição especifica, você deve usar o caractere [
e ]
quando estiver construindo um binding.
Veja como no exemplo abaixo:
Para acessar o título do segundo filme (“Contact”), use o binding @{movies.titles[1].title}
.
No Kotlin é necessário que se crie algumas classes para gerenciar os contextos multi-valorados
Container(
children = listOf(
Text("@{movies.titles[1].title}")
),
context = ContextData(
id = "movies",
value = Movie(
genre = "sci-fi",
titles = listOf(
Title(
title = "Inception",
year = "2010",
rating = "8.8"
),
Title(
title = "Contact",
year = "1997",
rating = "7.4"
)
)
)
)
)
class Movie(val genre: String, val titles:List<Title>)
class Title(val title:String, val year:String, val rating:String)
Bindings que se referem a contextos não existentes ou inválidos não podem ser atualizados e irão aparecer na tela da mesma forma que a string foi definida literalmente (no caso, se o atributo recebido é uma string).
Por exemplo, se você usar @{client.name}
e o "client"
o contexto não é acessível (declarado), se o binding não for substituído por nenhum valor. O mesmo aconteceria se o contexto “client” não existisse, mas o tem a propriedade “name”.
É possível usar mais de um binding em uma única string e eventos estáticos misturados com bindings.
Veja como no exemplo abaixo:
Exemplo: "Hello @{person.name}. Your score is @{score.value}."
Em cada sistema, o binding deve ser declarado de uma forma:
Bind
.Expression
para fazer o mesmo efeito que no Android.Exemplos de cada sistema operacional:
data class MyComponent(
val text: Bind<String>
) : WidgetView() {
override fun buildView(rootView: RootView): View {
val view = MyView(rootView.getContext())
// To make bind works you have to call the observeBindChanges method
// passing a rootView and the attribute that has a bind
observeBindChanges(rootView, text) { view.setText(it) }
return view
}
}
public struct MyComponent: Widget {
public var widgetProperties: WidgetProperties
public let text: Expression<String>
public func toView(renderer: BeagleRenderer) -> UIView {
let textView = UITextView()
// To make bind works you have to call the observeBindChanges method
// passing a rootView and the attribute that has a bind
renderer.observe(text, andUpdate: \.text, in: textView)
return textView
}
}
A forma de referenciar uma expressão em Kotlin DSL é:
MyComponent(
text = expressionOf("@{myContext.hello}")
)
No entanto, caso você passe o valor hardcoded, você deve fazer dessa forma:
MyComponent(
text = valueOf("hello")
)
Nesta seção, você encontra descrição completa das Operações.
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.