Skip to content
This repository has been archived by the owner on Jun 1, 2024. It is now read-only.

New feature: component interaction with events, actions, contexts and bindings #54

Closed
Tiagoperes opened this issue Apr 24, 2020 · 6 comments · Fixed by #190, #228, #237, #262 or #276
Closed
Assignees
Labels
android This issue directly affects structure and logic of Android project backend This issue directly affects structure and logic of Backend project iOS This issue directly affects structure and logic of iOS project

Comments

@Tiagoperes
Copy link
Contributor

Tiagoperes commented Apr 24, 2020

According to meeting we had in 04/22/2020. We should implement a new feature to facilitate the development of interactive interfaces with Beagle.

Today it can get very hard very easily when front-end developers try to implement any feature where a Beagle component must interact with another Beagle component. All this logic must be predicted by us and delivered through a base component or be implemented entirely by the end-developer. Generally, our libs get way too dependent in the components we offer and, since we can't predict every use case, the end-developer will have to implement very complex components which will most of the time also be coupled with the Beagle libraries.

To eliminate this problem, in the aforementioned meeting it was proposed a new feature that allows for state sharing between components and its manipulation. Four new concepts were proposed: events, actions, contexts and bindings.

The four new concepts (events, actions, contexts and bindings) must be implemented in all of the Beagle Projects (schema, bff, ios, android and web). To implement these, the specification hosted here must be followed. All of the examples showed during the meeting are hosted online and a link to each of them can be found at the end of specification document.

Any proposition to change anything in the specification must be done through a Pull Request in this repository.

@Tiagoperes Tiagoperes added android This issue directly affects structure and logic of Android project backend This issue directly affects structure and logic of Backend project iOS This issue directly affects structure and logic of iOS project schema labels Apr 24, 2020
@Tiagoperes
Copy link
Contributor Author

Tiagoperes commented Apr 24, 2020

Here are some diagrams to show the general idea behind the implementation of these features in Beagle WEB. It is absolutely not necessary to follow these diagrams, if the specification is respected, then it's all fine. The diagrams are just to give a better idea of the strategy we used to develop this in the Beagle React library.

Link to the diagrams: https://app.diagrams.net/?lightbox=1&highlight=0000ff&edit=_blank&layers=1&nav=1&title=Beagle%20Web%20-%20Rendering.drawio#Uhttps%3A%2F%2Fdrive.google.com%2Fuc%3Fid%3D1JOTjPITYxJLIUzylY_s-0Mg--Hz-aIIi%26export%3Ddownload

@tuliopereirazup tuliopereirazup added this to To do in Beagle Android via automation Apr 28, 2020
@tuliopereirazup tuliopereirazup moved this from To do to In progress in Beagle Android Apr 28, 2020
@tuliopereirazup tuliopereirazup self-assigned this Apr 28, 2020
uziasferreirazup pushed a commit that referenced this issue Apr 30, 2020
* flex refactor

* flex fixture fix

* Adding some tests to Stack and Horizontal

* Flex, FlexEntity and YogaTranslator unit tests

* Fixing tests

* FlexViewConfigurator tests
uziasferreirazup pushed a commit that referenced this issue Apr 30, 2020
* change openview to swapview, added poptoview and presentview

* code indentation
@tuliopereirazup
Copy link
Contributor

tuliopereirazup commented May 4, 2020

Problems in Android

[ ] Create the reactive expression evaluation. Every item on context should be reactive, if any of them change, it need to be evaluated again.
[ ] Generate code to handle widget's value observation. If any value on context change, any widget that is observing the context should be updated with its new value.

Example for problem two:

// Generate class that represent the annotated Widget with @RegisterWidget
data class MyWidgetBinding(
    val test1: Bind<Int>,
    val test2: Bind<Boolean>,
    val test3: Bind<Array<String>>,
    val test4: Bind<InternalObject>
) : ServerDrivenComponent

// Generated class that is responsible to observe the changes of every Bind attribute and notify the annotated widget in onBind method.
class MyWidgetModelBindingAdapter(
    private val widget: BindingWidget,
    private val binding: MyWidgetBinding
) : BindingAdapter {

    override fun getBindAttributes(): List<Bind<*>> = listOf(
        binding.test1,
        binding.test2,
        binding.test3,
        binding.test4
    )

    override fun bindModel() {
        val myWidget = MyWidget(
            test1 = binding.test1.value,
            test2 = binding.test2.value,
            test3 = binding.test3.value,
            test4 = binding.test4.value
        )

//TODO understand how to get the myWidgetView variable

        binding.test1.observe {
            widget.onBind(myWidget.copy(test1 = it), myWidgetView)
        }
        binding.test2.observe {
            widget.onBind(myWidget.copy(test2 = it), myWidgetView)
        }
        binding.test3.observe {
            widget.onBind(myWidget.copy(test3 = it), myWidgetView)
        }
        binding.test4.observe {
            widget.onBind(myWidget.copy(test4 = internal), myWidgetView)
        }
    }
}

interface BindingAdapter {
    fun getBindAttributes(): List<Bind<*>>
    fun bindModel()
}

interface BindingWidget : ServerDrivenComponent  {
    fun onBind(widget: Widget)
}

@uziasferreirazup uziasferreirazup added this to To do in 1.0.0 via automation May 11, 2020
Tiagoperes added a commit to ZupIT/beagle-web-core that referenced this issue May 11, 2020
…pressions) (#53)

# Feature de ações

Com essa nova feature, agora é possível:
- estabelecer comunicação entre componentes;
- carregar partes da árvore dinamicamente (lazy loading);
- separar apresentação do modelo de dados;
- navegar entre telas do Beagle;
- dentre outros (consulte a [especificação](https://github.com/ZupIT/beagle-web-core/tree/specification/component-interaction) para mais detalhes).

Os seguintes conceitos foram implementados:
- eventos;
- ações;
- contextos;
- bindings (expressions);
- navegação.

## Issues resolvidas
- [Estudar e implementar meios de estabelecer comunicação entre componentes do Beagle](#12)
- [New feature: component interaction with events, actions, contexts and bindings](ZupIT/beagle#54)

## Especificação implementada
- [Especificação - Eventos, Ações, Contextos e Bindings](https://github.com/ZupIT/beagle-web-core/tree/specification/component-interaction)

## Pull requests relacionados:
- [Angular](ZupIT/beagle-web-angular#54)
- [React](ZupIT/beagle-web-react#13)
@tuliopereirazup tuliopereirazup moved this from To do to In progress in 1.0.0 May 11, 2020
@Tiagoperes
Copy link
Contributor Author

Tiagoperes commented May 11, 2020

These features were implemented in web-core (0.0.16), web-react (0.0.16) and web-angular (0.0.16).

If the specification is, for some reason, changed, new issues should be opened in the web projects so we can make the modifications needed.

@hernandazevedozup
Copy link
Contributor

hernandazevedozup commented May 25, 2020

TODO LIST ANDROID/ BACKEND

@Tiagoperes
Copy link
Contributor Author

Tiagoperes commented May 27, 2020

Edit: I forgot this should be written in english :(


Changes resulting from the meeting of 05/27/2020:

  • The form component implemented today (beagle:form) continues to exist, but it will be deprecated in V1 and futurely removed.
  • New component beagle:simpleform should be implemented as a new default component. beagle:simpleform should be rendered just like a container in mobile apps and as the html tag <form> in web applications. beagle:simpleform receives the same properties as beagle:container and one more: onSubmit. onSubmit is an event (can be associated with an action or array of actions) that is triggered every time the form is submitted.
  • A new default action should be implementes: beagle:submitForm. This action should not receive any additional parameter and its only function is to submit the parent form.
  • The reset event of the form has been removed.
  • _context_ won't be valid for any component that accepts children, now, _context_ is only valid for components that implement LayoutComponent. They are:
    • container
    • form
    • simpleForm
    • screen
    • scrollView
    • lazyComponent
    • listView
    • pageView
    • custom components implementing LayoutComponent

PS: everything done with the simpleform can be done without it. This component and the submitForm action were created mainly for accessibility reasons. In web apps, we can't render everything as div's and expect robots to correctly identify what is a form and how to submit it. Furthermore, it is more intuitive to build a form in the declarative language than it is to build a container, a button and link them with actions.

@Tiagoperes
Copy link
Contributor Author

URL to examples on beagle web was updated: https://beagle-playground.netlify.app/#/demo/component-interaction

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.