Giter VIP home page Giter VIP logo

yysun / apprun Goto Github PK

View Code? Open in Web Editor NEW
1.2K 34.0 59.0 26.97 MB

AppRun is a JavaScript library for developing high-performance and reliable web applications using the elm inspired architecture, events and components.

Home Page: https://apprun.js.org

License: MIT License

TypeScript 93.52% JavaScript 3.35% HTML 3.13%
javascript typescript framework state-management router component virtual-dom event-driven

apprun's Introduction

AppRun Build NPM version Downloads License twitter Discord Chat

AppRun is a JavaScript library for building reliable, high-performance web applications using the Elm-inspired architecture, events, and components.

// define the application state
const state = 0;

// view is a pure function to display the state
const view = state => `<div>
  <h1>${state}</h1>
  <button onclick="app.run('-1')">-1</button>
  <button onclick="app.run('+1')">+1</button>
</div>`;

// update is a collection of event handlers
const update = {
  '+1': state => state + 1,
  '-1': state => state - 1
};
app.start(document.body, state, view, update, { transition: true });

Note, the transition option is newly added to enable the View Transition API during the rendering of the view.

AppRun Benefits

  • Clean architecure that needs less code
  • State management and routing included
  • No proprietary syntax to learn (no hooks)
  • Use directly in the browser or with a compiler/bundler
  • Advanced features: JSX, Web Components, Dev Tools, SSR, etc.

Getting Started

AppRun is distributed on npm. To get it, run:

npm install apprun

You can also load AppRun directly from the unpkg.com CDN:

<script src="https://unpkg.com/apprun/dist/apprun-html.js"></script>
<script>
  const view = state => `<div>${state}</div>`;
  app.start(document.body, 'hello AppRun', view);
</script>

Or, use the ESM version:

<script type="module">
  import { app } from 'https://unpkg.com/apprun/dist/apprun-html.esm.js';
  const view = state => `<div>${state}</div>`;
  app.start(document.body, 'hello ESM', view);
</script>

Or, you can create an AppRun app by using the npm create apprun-app command.

npm create apprun-app [my-app]

Component and Web Component

An AppRun component is a mini-application with elm architecture, which means inside a component, there are state, view, and update. In addition, components provide a local scope.

class Counter extends Component {
  state = 0;
  view = state => {
    const add = (state, num) => state + num;
    return <>
      <h1>{state}</h1>
      <button $onclick={[add, -1]}>-1</button>
      <button $onclick={[add, +1]}>+1</button>
      </>;
  }
}
app.render(document.body, <Counter/>);

You can convert AppRun components into web components/custom elements. AppRun components become the custom elements that also can handle AppRun events.

class Counter extends Component {
  state = 0;
  view = state => {
    const add = (state, num) => state + num;
    return <>
      <h1>{state}</h1>
      <button $onclick={[add, -1]}>-1</button>
      <button $onclick={[add, +1]}>+1</button>
      </>;
  }
}
app.webComponent('my-app', Counter);
app.render(document.body, <my-app />);

All the Ways to Make a Web Component - May 2021 Update compares the coding style, bundle size, and performance of 55 different ways to make a Web Component. It put AppRun on the top 1/3 of the list of bundle size and performance.

Learn More

You can get started with AppRun Docs and the AppRun Playground.

AppRun Book from Apress

Order from Amazon

Contribute

You can launch the webpack dev-server and the demo app from the demo folder with the following npm commands:

npm install
npm start

You can run the unit tests from the tests folder.

npm test

Unit tests can serve as functional specifications.

Finally, to build optimized js files to the dist folder, just run:

npm run build

Have fun and send pull requests.

Contributors

Support

AppRun is an MIT-licensed open source project. Please consider supporting the project on Patreon. πŸ‘β€οΈπŸ™

Thank you for your support

  • Athkahden Asura
  • Alfred Nerstu
  • Gyuri Lajos
  • Lorenz Glißmann
  • Kevin Shi
  • Chancy Kennedy

License

MIT

Copyright (c) 2015-2022 Yiyi Sun

apprun's People

Contributors

artiumdominus avatar ericsun-brps avatar ishanray avatar jamievaughn avatar ludmiloff avatar mnorrish avatar phbalance avatar roa-nyx avatar sebring avatar spurreiter avatar tskovlund avatar vitorluizc avatar yurovant avatar yysun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apprun's Issues

[Question] Diferent way of declare a webcomponent

In the examples and documentation I saw two diferents ways of declare a web component, with constructor and without them, why?

Constructor:

    class Counter extends Component {
      constructor() {
        super();
        this.state = 0;
        this.view = state => `<div>
          <h1>${state}</h1>
          <button onclick='counter.run("-1")'>-1</button>
          <button onclick='counter.run("+1")'>+1</button>
          </div>`;
        this.update = {
          '+1': state => state + 1,
          '-1': state => state - 1
        };
      }
    }

No constructor:

export default class CounterComponent extends Component {
  state = 'Counter';
  view = state => {
    return <div>
      <h1>{state}</h1>
    </div>
  }
  update = {
    '#Counter': state => state,
  }
}

πŸ€”

Small typo in docs/README.md

On β‰ˆ line 218 in apprun/blob/master/docs/README.md, the line console.log(sate); should be changed into console.log(state);.

Component state?

I'm taking another look at AppRun after more than a year. I love the component concept with the state/view/update approach! So I was pretty excited to try this out :-)

Just trying this out on the playground for now.

So I took the "parent/child" and the Counter component example from the docs, and I get something like this:

class Counter extends Component {
  state = 0;
  view = state => (
    <div>
      <h1>{state}</h1>
      <button $onclick='-1'>-1</button>
      <button $onclick='+1'>+1</button>
    </div>
  );
  update = {
    '+1': state => state + 1,
    '-1': state => state - 1
  };
}

class App extends Component {
  state = {};
  view = state => (
    <div>
      <Counter />
    </div>
  );
  update = {};
}

// new Counter().start(document.body); // works fine

new App().start(document.body); // doesn't maintain state?

I thought I was following the documentation basically straight up - but it doesn't work. The Counter instance either doesn't maintain state, doesn't update, or doesn't respond to the $onclick messages - I can't tell which. There are no error messages in the console or anything, it just doesn't update.

Inspecting the DOM, I don't see any event-handlers attached to the click event on the button elements:

image

Compare this with mounting the Counter component directly, which works fine:

image

What am I missing? πŸ€”

SVG in JSX

Hello,

I can't return svg through jsx.
Do you have a clue ?

Regards

Using "app.run()" outside view and state

Hi, @yysun ! First let me congratulate you for this great job.

I've been experimenting to build my own components using lots of different frameworks outthere to see which one suits best for me. Now that I found AppRun, with this ELM approach (a very good choice of yours!), I think I found what I want.

My first component is a simple countdown timer, nothing fancy, but usefull and good for my trials. I'm passing to it 2 parameters:

  • init = a number (in seconds) to begin the countdown
  • blink = another number so the counter starts blinking (to advice it's almost ending).

I`m having some trouble, most likely due my inexperience, on calling app.run( "reset" ) - in fact, this.run( "reset" ) - on Constructor method. My code is like this:

export default class LwbTimerComponent extends Component {

  constructor( { init, blink } ) {
     super();
     this.initCounter = init;
     this.initBlink = blink;
     this.run( "reset" );   //  *** app.ts:30 Assertion failed: No subscriber for event: reset ***
     this.ptTimer = setInterval( () => this.run( "decrease" ), 1000 );
  }
  model = {
     secondsToGo: this.initCounter,
     ...
  }
  view = { ... }
  update = {
    "#LwbTimer": model => model,
    "decrease" : model => { ... },
    "reset": model => { 
         model.secondsToGo = this.initCounter;
         ... 
    },
   "blink": model => { ... },
 }
}

The compiler is telling me that "Assertion failed: No subscriber for event: reset" on run.app( "reset" ).
Clearly I defined "reset" event on update method, but something is missing.
What am I doing wrong?

How to code "disabled"?

In my little toy project, which is just a single html file, I want to disable a button, depending on some condition. I obviously haven't found the right way to code that condition. Here is my code:

<button onclick='app.run("remove")' disabled="${arr.length < 2}">Remove Last</button>

This way, the button gets disabled no matter the length of arr.

I just found this solution, however:

<button onclick='app.run("remove")' ${arr.length < 2 ? 'disabled' : ''}>Remove Last</button>

updateProps incorrectly handling data-*, role, and class[Name] attributes

Hi,
using apprun for a small website I came across some rendering mistakes that are occurring when reusing tags (which just modifies the tag's attributes):

  1. data-* isn't removed correctly. The element.dataset property should be deleted.
  2. role should be removed if there is no value
  3. class[Name] needs to have removeAttribute called when removing it as setting element.className="" leaves the class attribute although it does successfully remove its value.

I'm happy to generate a pull request.

apprun-dev-tools.tsx:183 Uncaught TypeError: Cannot read property 'connect' of undefined

Congratulations for this excellent work.
I really believe that you have achieved good architecture for the frontend.

I am studying it very carefully, but I still get lost in some concepts.
Anyway, I do not know if this is an issue, but I mention that simply with npx apprun -i && npm start, I already have this error in the console:

AppRun DevTools 0.2: type "_apprun help" to list all available commands.
apprun-dev-tools.tsx:183 Uncaught TypeError: Cannot read property 'connect' of undefined
at Object.12 (apprun-dev-tools.tsx:183)
at t (bootstrap:19)
at 0 (bootstrap:83)
at bootstrap:83
at universalModuleDefinition:9
at universalModuleDefinition:1

but _apprun 'components' show this
apprun-dev-tools.tsx:133 <div id=​"my-app">​<div>​<h1>​Hello world - AppRun !​</h1>​</div>​</div>​ [{…}]
<- undefined

Thanks in advance.

How to get new value of 'input' when not using JSX/compiler?

In my toy AppRun project I still try to avoid using any compiler or build tool, just everything in a single file. However, now I need to obtain the new value of an <input type="text" ...> element, and I'm not sure if it can be done by including an oninput attribute like the one below, since this will not refer to the input element:

oninput="app.run('input_evt', ...this.value...)"

Is there a simple solution to this?

Does appRun support shared state?

Does appRun support the concept of an app-wide shared state (with associated actions and vies/getters) , like you have with the likes of vuex, mobx-state-tree. or would it work with a state management library like mobx or mobx-state-tree

Improve Example

Hi,

at the moment I'm working on an demo todo application
) where the frontend is based on AppRun and the backend on Spring Boot.

My "problem" now is to understand the "right way" to call backend api (expose by rest) from the frontend.
Can you give me a simple example, please?

Thanks,
Andrea

AppRun + other compile-To-JS languages?

Hello,

Would it be possible to use AppRun with some functional languages compiled to JS? I am looking for some small footprint solution (would love to use ClojureScript, but its big loading to the browser).

Have been thinking about one of the following:

AppRun + https://github.com/BuckleScript/bucklescript
AppRun + https://github.com/fable-compiler/Fable
AppRun + https://github.com/anko/eslisp
AppRun + https://github.com/jbr/sibilant
AppRun + https://github.com/purescript/purescript

Can you give me some info, hint on that?

Thank you! :)
Best regards,

Tom

Routing without hash tag

Hi, yysun
I feel really excited about this library after seeing frontend framework performance benchmark you mentioned in README.

I am wondering if I can have routing without hashtag? Thanks for your kind reply.

Multiple apps

Hello,

Is having multiple apps in a page a bad practice ?

Regards

Roadmap for Apprun

Hi,

Thank you for creating Apprun. Have been following your creation with great interest recently. Love the clean way and no boilerplate.

You have done quite a bit on the documentation side as well, helping to get a better understanding of Apprun. Sure, a lot more could be added in the future. I've also seen a lot of different approaches and versions.

I'm at the beginning of exploring the possibilities for real use, and still in doubt choosing between Apprun or Hyperapp (mainly because of larger userbase and contributors).

What might be helpful would be a roadmap, to get a better grasp of the future of Apprun. Perhaps you can find the time to add a few lines about it in the docs? It can help as well to attract new users.

Regards.

Is possible render 'Fragments' like in react?

In react is possible render fragments:

A common pattern in React is for a component to return multiple elements. Fragments let you group a list of children without adding extra nodes to the DOM.

in apprun I do can the same?

Thank u.

New view includes element from old view

I ran into a very simple case which seems like unusual behavior to me, but I'm not sure if it's by design or not.

In the example below, the <button> is being rendered in the new view even though it should be a solitary <div>. If I wrap the entire view in another <div>, then we get the proper behavior. If this is by design, that the view must be wrapped in a single top-level element, I wonder if there's a way to emit an error when someone experiments with a view as below?

<html>

<head>
    <script src="https://unpkg.com/apprun@latest/dist/apprun-html.js"></script>
</head>

<body>

<div id="file-processor"></div>

<script>

function read_files(state){
    const el = document.getElementById('file-upload');
    state.files = el.files;
    return state;
}

const state = {
    files: []
};
const view = state => {
    var new_view = null;
    if (state.files.length == 0){
        new_view = `<input type="file"
            id="file-upload" name="files"
            accept=".csv"
            multiple>

        <button onclick='app.run("read-files")'>Load Files</button>`;
    }
    else {
        new_view = `<div>Files: ${state.files.length}</div>`;
    }
    return new_view;
};
const update = {
    'read-files': state => read_files(state),
};
app.start('file-processor', state, view, update);

</script>
</body>
</html>

npm start on default SPA results in errors

I ran apprun -i --spa and it seemed to install correctly.

Then I ran npm start and I get the following errors:

ERROR in ...\Home.spec.ts
[tsl] ERROR in ...\Home.spec.ts(4,1)
      TS2304: Cannot find name 'describe'.

ERROR in ...\Home.spec.ts
[tsl] ERROR in ...\Home.spec.ts(5,3)
      TS2304: Cannot find name 'it'.

ERROR in ...\Home.spec.ts
[tsl] ERROR in ...\Home.spec.ts(9,5)
      TS2304: Cannot find name 'expect'.

ERROR in ...\Contact.spec.ts
[tsl] ERROR in ...\Contact.spec.ts(4,1)
      TS2304: Cannot find name 'describe'.

ERROR in ...\Contact.spec.ts
[tsl] ERROR in ...\Contact.spec.ts(5,3)
      TS2304: Cannot find name 'it'.

ERROR in ...\Contact.spec.ts
[tsl] ERROR in ...\Contact.spec.ts(9,5)
      TS2304: Cannot find name 'expect'.

ERROR in ...\About.spec.ts
[tsl] ERROR in ...\About.spec.ts(4,1)
      TS2304: Cannot find name 'describe'.

ERROR in ...\About.spec.ts
[tsl] ERROR in ...\About.spec.ts(5,3)
      TS2304: Cannot find name 'it'.

ERROR in ...\About.spec.ts
[tsl] ERROR in ...\About.spec.ts(9,5)
      TS2304: Cannot find name 'expect'.
webpack: Failed to compile.

Maybe I'm doing something wrong?

SSR with node

Hi @yysun i saw the SSR example using Asp.NET . how do we set up SSR with node , and maybe using a bundler like parcel.js or webpack. Thanks for this solid library

AppRun + office-ui-fabric-react, is it possible?

I'm new to AppRun and React. I really like what I see in AppRun given my reading/research of Elm!

Likely a naive question, but I was wondering if an AppRun app could use React components?

Apologies if this is the wrong place to ask questions like this.

Thanks,
Tom

Run code after render (e.g. set focus)

Hey thank you so much for this awesome framework. I have used it for many small projects and am in the middle of a larger one now. One thing I am unsure how to do is setting focus on an input once the page has been rendered. I think I can just set a timeout in the constructor but I would prefer a cleaner more 'apprun' way of doing it.

Is there currently a way to do that?

Silent failure if the view starts with a space or newline

AppRun seems to silently produce nothing if there's a space or newline before the first element in the view. I noticed this initially when using the backtick string form, e.g.:

return `
<div>
  <div>hello</div>
  <div>world</div>
</div
`

The code below produces the issue for me on AppRun version 1.13.8 and Chrome 67:

<html>
<head>
    <script src="https://unpkg.com/[email protected]/dist/apprun-html.js"></script>
</head>

<body>
    <div id="app-content">
    </div>

    <script>
        const state = {};
        const view = state => {
            return ' <div>hello</div>';
        };

        const update = {
        };
        app.start('app-content', state, view, update);
    </script>
</body>
</html>

Web Component

Hello,

Thanks for AppRun

Could publish on StackBlitz a working sample of a counter compoment (not the list one)?
Thanks
Regards

Websocket example?

I'd like to open a websocket once and have various components listen for different events. How would I do something like that?

ie. Create one web socket connection, receive message data from server, update chart component with message, update geomap component with message.

Thanks in advance.

ES6 app run

Hello, I would like to write apprun applications without using typescript is this a possibility?

Does using JSX syntax like onclick={...} require build tools?

My AppRun projects this far have been small toy apps, experiments that can be run in my BBEdit editor without any build tools at all. However, when I tried to do something like this (described in the docs as JSX syntax):

<input type="text" onchange={() => app.run("INP", rowIdx)}>

then the code after the =>ended up outside the input element, as text.
I also tried this, with no success:

<input type="text" onchange={function() {app.run("INP", rowIdx);}}>

Does this mean that I have to use some build tools including transpiling for that JSX syntax to be accepted?

I looked for examples using onchange= in the code at https://github.com/yysun/apprun-examples but found none, just a few using onclick=.

Webcomponent example from https://apprun.js.org/ fails

I naively pasted the web component example (https://apprun.js.org/) into a somefile.html and than opened it with the browser.
The counter and the buttons will be displayed but clicking the buttons does not have an effect. In the console log I see an error when loading the html:

TypeError: this._component.mounted is not a function

and when clicking the buttons I get:

TypeError: counter.run is not a function

There is probably something that I am missing.

"onclick" is not rendered in button element

Hi, I'm try this great library, but i am frutrated by a mistake, I'm follow the apprun + parcel example but i don have the render expected for the button element, I expect:

<button onclick="app.run('+1')">+1</button>

But, I only got:

<button>+1</button>

I don't understand why!, =(

PD: I don't got any error in console.

Please check it out my project =)

What's wrong with .map((x, i) => { return `<foo>`; }).join("") ?

To generate e.g. the rows in a table, I often use code like

${rowdata.map((x, i) => `<tr>. . .</tr>`).join("")}

However, if I need to do something, like calculating a value v, before returning the <tr> code, then the following syntax should have been possible:

${rowdata.map((x, i) => { const v = . . .; return `<tr>. . .</tr>`; }).join("")}

. . . but it seems to me that AppRun doesn't like that. Is that documented somewhere?

IE11 ...

I wondered if apprun runs on IE11, i have tried on Stackblitz it works.
You can close this issue

Regards

Fetch data before render

How I can fetch data and put in state before render?
Is there way to do it like componentDidMount in React?

How to set aria-* attributes

Hello @yysun, thank you for your effort on building this awesome framework.

The problem I faced is I'm not able to setup aria-* attributes, aria-label in particular with JSX/TSX syntax. What is strange, I'm able to successfully set data-id attribute which is quite similar.
the code to reproduce:
<form role="search"><input type="search" className="hsi" aria-label="Search"/></form>
do not set aria-label attribute.

As I see, the jsx/react namespace is bound to apprun itself which correctly create element structure with all attributes, then somehow it is transformed into DOM element without aria-label;

Can you point me what is wrong.

UPDATE:
vdom-my.ts
function updateProps(....)

just recognize some attributes like data-id, and tries to set others as attributes to DOM element, but desired behaviour should be to add the attribute to internal attributes map . I'm pretty sure I can prepare a pull request with desired code, at least with aria-* subset.

Question about using JSX

Hello,

In Stackblitz, you use import React from 'apprun in order to use JSX.
Could you explain how it is used and how you get rid of React in th build dist ?

Regards

Property className cannot be assigned to Component's wrapper div

AppRun always wraps up Component in an extra div. It's not so convenient from CSS point of view, but it even less convenient that a developer cannot add any CSS style rules to the wrapping (parent) div by CSS class name, because it looks like the only property Component's parent div handles is Id.
If there is no way to remove parent extra div could you add an ability to define className property to the parent div?

Stateful components

Just started looking at AppRun last night, and really like the design/concept! Very elegant πŸ‘

I noticed in the documentation that stateful components are "work in progress" - I was wondering if you can elaborate a little bit?

I'm trying to figure out if this feature (or a planned future feature) satisfies my use-case.

As far as my understanding, components in AppRun are very different from components in, say, React - I think the best way I can explain my understanding of the conceptual difference is, AppRun components are "components of the application", while React components are "components of the UI".

While components in AppRun provide a useful abstraction of a self-contained section of the UI state and view, presumably stateful components will provide an abstraction of UI "controls", e.g. components that have an internal state?

I recently explained it to someone like this:

There is application state, and there is control state.

Control state really pertains only to a control while it exists, and becomes completely irrelevant the moment the control disappears from the user's view: whether a date-picker or drop-down was open, where the cursor was located in an input, and so on - no longer relevant once the control is gone.

We don't need or expect or want such state to persist in the model - most of the time, we don't even care that it exists, for example, we don't typically care if a drop-down is open, we just want a notification when a selection is made.

Am I right to think this is the purpose of stateful components in AppRun?

Will we be able to instanciate these components via JSX, similarly to how all components are instanciated in for example React?

Or where do you see this feature heading?

Thanks :-)

Suggestion

Hy,

Adding real time to apprun would be nice.
I have a project in mind (simple dating for geeks), I intend to use apprun and feathersjs

Regards

'this' is undefined inside @update decorated function

Example code to reproduce:

export default class TestComponent extends Component {
  state = '1';

  view = (state) => {
    return <div>
      <h1>Test</h1>
      <button onclick={_ => this.run('test')} >Test</button>
    </div>
  }

  @update("test", {render: true})
  onTest(state) {
    console.assert(this !== undefined, "'this' is undefined")
    return state;
  }

  // @on("test1")
  // test = (state) => {
  //   console.assert(this !== undefined, "'this' is undefined")
  //   return state;
  // }

  update = {
    '#TTT': state => state,
  }
}

But when @on('test') test = (state) => {....} is uncommented, (note @on is on another message) then assertion is ok;
If only @on decorator is used then everything works well too.
Hope I've explained it.

Reusable component with private and public handlers

Hello!
First of all thanks for the good framework.

Taking into account the basic example on the first page of Github, could you explain how can I create reusable component that will have private handlers and public, please.
For example I want to create a Counter component. After that I want to create a set of these Counters.
Each of the counters should have internal handlers and several public. If I need increment only one counter I invoke private or personal handler and if I want to increment all counters I invoke public handler that affects all counters via app.run.

Thank you in advance.

No 404/default route handling

Hi,
unless I'm missing something, I don't see any "normal" way to catch an attempt to route to a URL which doesn't exist (e.g. 404 or mistake in code matching an href to component event) unless I want to separately register all my routes and check them in the '//' event or create my own router.

I have some code which implements a default route handler by returning the number of subscribers from app.run and then invoking a default event ('///' perhaps) from within the router if there are no subscribers to the URI. Shall I generate a pull request or is there some other way I've missed?

Allow ROUTER_EVENT handler (//) to stop propagation of other event (#SomeComponent)

There are certain cases when firing #SomeComponent event from router should be stoped if no conditions met.
Example:
User click on link witch leads to restricted area (user profile etc) and login form must be popped first, then on successful login the page should be displayed.

If I'm able to catch such route in (//) handler and stop #Profile event, I could easily fire #Login event with proper parameter #Profile as returnURL.

With current router implementation I'm firing the another event (#Login), but #Profile event is fired too.

State-based <input> tag renders incorrectly, possible problem with virtual dom diffing

I have the following view function:

  view = (state) => {
    return <div>
      <h1>Welcome to the app!</h1>
      <form id="login" action="api/login.php" method="POST" onsubmit={(ev) => {
        this.run('login:submit', ev);
        return false;
      }}>
        <input type="email" name="email" placeholder="[email protected]" required />
        {state === 'login:signup' ? <input type="text" name="name" placeholder="Your name" required /> : ''}
        <input type="submit" />
      </form>
    </div>;
  }

Basically it's a form with a single input unless state === 'login:signup' where by it will have two inputs (email and name).

This is working fine:

  • On initial load I only see the email input
  • When state changes to login:signup I see both email and name inputs

However, when state reverts back to anything other then login:signup the name input remains!

I know virtual dom diffing algorithms have lots of trouble dealing with inputs. I wonder if this might be an issue there?

router improvements: HTML 5 history & "pretty" links

Hi,
presently HTML 5 history and "pretty links" aren't implemented although most of the required code is in the router already. In particular here are the issues as I see them:

  1. No obvious way to initialize the router to indicate if the link approach is going to be # (location.hash) or / (location.pathname) based. Possible changes:
    a. we could add a method to app.router to allow the user to set the link approach.
    b. we could attempt to guess based on the first character of the hash and pathname. I'm not sure if there are situations where we could have problems but is there any reason to support a mix of hash and pretty links on a page?

  2. Link behaviour for pretty links needs to modify the default behaviour which is to GET the href. Possible changes:
    a) This is fairly easy to do outside of apprun (onclick = e => { app.route(e.currentTarget["href"]); return false;}) so we could get away with nothing changed inside apprun.
    b) The question is if it makes sense for apprun to have some kind of api exposed to make it easier to do these kind of links (say app.routerLink), require some attribute (say data-apprun-link) that is looked for during rendering, or if it should just be kept as a non code bit of functionality? I'm more in favour of something like each link being decorated with onclick = e => app.routerLink(e) as app is a global and easily accessible in javascript.

What are your thoughts?

Thanks,
Peter

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.