antonmedv / monkberry

Monkberry is a JavaScript library for building web user interfaces
https://monkberry.js.org
MIT License
1.49k stars 78 forks source link

Trying to route #33

Open cezarsmpio opened 7 years ago

cezarsmpio commented 7 years ago

Hi guys, how are you? I have used React a lot, but I'm trying to change to something simplest.

I'm trying to implement a route system using the lib director. My code is very simple, just to study the monkberry.

Ok, let me show my code: app.js

import Monkberry from 'monkberry';
import App from './views/app.monk';
import RecoverPassword from './views/recuperar-senha.monk';

import {Router} from 'director';

const node = document.querySelector('#app');

const router = Router({
  '/': function () {
    Monkberry.render(App, node);
  },
  '/recover-password': function () {
    Monkberry.render(RecoverPassword, node);
  }
});

router.init('/');

I don't know if I understand what is the method render, but it's "appending" my templates, not "replace" them.

Follow a GIF example to demonstrate what's happening: zx5ovcsccf

Ok, I don't know If I doing a mistake or there is a other way simpler to create a route, but the only resource that I found was the #8 :/

One more thing: There is something like React this.props.children in Monkberry or a solution like React?

Thanks!

benjamminf commented 7 years ago

Why don't you just empty out the node before rendering?

while (node.firstChild) node.removeChild(node.firstChild);
Monkberry.render(App, node);
cezarsmpio commented 7 years ago

I'm finding some solutions, I'm doing something using the own events from director router:

router.configure({
  // Before enter in a route
  before: function () {
    node.innerHTML = ''; 
  }
});
benjamminf commented 7 years ago

That looks fine to me 👍

agauniyal commented 7 years ago

@cezarlz would you mind telling how are you using monkberry with es6 syntax - gulp + browserify?

cezarsmpio commented 7 years ago

Hi @agauniyal, I'm using es6 with babel and webpack only. The monkberry provides a loader to work with Webpack.

I created a gist with my configs: https://gist.github.com/cezarlz/f75ac0878994135c168432732dc560e7

Thanks!

PierBover commented 7 years ago

Is there any recommended router for Monkberry?

Not having a router is probably the biggest drawback of the library IMO.

cezarsmpio commented 7 years ago

@PierBover I'm using an approach with director.js, but I don't know if the "approach" is the best way. I tried follow using something like "containers".

For example:

import {Router} from 'director';

// Containers
import App from './containers/appContainer';

// Components
import IndexComponent from './components/index';
import RecuperarSenhaComponent from './components/recuperarSenha';

const node = document.querySelector('#app');

const routes = {
  '/': App.bind(null, IndexComponent, node),
  'recover-password': App.bind(null, RecuperarSenhaComponent, node)
};

const router = new Router(routes);

router.configure({
  before: function () {
    node.innerHTML = '';
  }
});

router.init('/');

Containers

import Monkberry from 'monkberry';
import children from '../directives/children';

import App from '../views/app.monk';

export default function (component, node) {
  const view = Monkberry.render(App, node, {
    directives: { children }
  });

  view.update({ component })
};

Directive

export default class {
  constructor() {
    this.node = null;
  }

  bind(node) {
    this.node = node;
  }

  unbind() {
    this.node = null;
  }

  update(component) {
    component(this.node);
  }
};

View

{% import Header from '../partials/header.monk' %}

<div id="app-container">
  <div class="form-index">
    <Header />

    <div class="form-content" :children={{ component }}></div>
  </div>

</div>

It's works correctly, but I'm afraid about this way is performatic.

Someone has a better idea?

Thanks!

PierBover commented 7 years ago

Would be awesome if @elfet could chime in!

antonmedv commented 7 years ago

Hi, all.

lets start from what Monkberry is just a library for transformation from state -> DOM. There is no best way to "route" or state management. You can use in that ever you want to. For me its redux + monkberry plays well. I'll write an article about this if i have time.

cezarsmpio commented 7 years ago

Hi @elfet, do you have some news about the articles? Thanks!

antonmedv commented 7 years ago

No, hope next month.

muthumani-prabhu commented 7 years ago

Tried solving the problem using monkberry remove method (stolen the idea from redux + todomvc). It works perfectly.

/**

Here is the director snippet which remove the view using "after" event, when the user is navigating away

import Monkberry from 'monkberry';
import App from './app/app.monk';
import RecoverPassword from './account/recover-password.monk';

import {Router} from 'director';
  const router = Router({
          '/': {
            'view': null,
            'on': function () {
                this.view = Monkberry.render(App, document.body);
            },
            'after': function () {
                if (this.view != null && this.view.remove) this.view.remove();
                this.view = null;
            }
          },

          '/recover-password': {
            'view': null,
            'on': function () {
                this.view = Monkberry.render(RecoverPassword, document.body);
            },
            'after': function () {
                if (this.view != null && this.view.remove) this.view.remove();
                this.view = null;
            }
          }
        });

    router.init('/');

@elfet, Would you please spare couple of minutes and confirm that the approach is correct? By the way I am really happy to see such a great simple framework, kudos to your efforts.

antonmedv commented 7 years ago

@muthumani-prabhu i confirm, thanks) Everything what works for you is solution. 😄