Skip to content
David Jensen edited this page Mar 8, 2016 · 2 revisions

Schema Form Core

...or "how to decouple what can be decoupled from angular 1.x"

Why?

First off, why would we like to get rid of Angular? We'll the aim is not to get rid of angular everywhere, just in the parts that really doesn't need angular.

With this we could gain some nice things:

  • Shared code between different ports of Schema Form. This is the main reason.
  • Easier upgrade/port to Angular 2
  • Possibility of server side use.
  • Future proofing.

What could a "core" include?

Basically the core parts are the services that take care of parsing the schema and the user supplied form and the builder that constructs the DOM.

In detail that should mean these should be in core:

  • services/Select.js
  • services/builder.js
  • service/errors.js - at least the error message constants.
  • services/schemaForm.js
  • services/validator.js
  • sfPath.js

It's debatable if servieces/errors.js and services/validator.js should be in core since they both mean that core would need to depend on tv4. But on the other hand all (javascript) ports would otherwise need to have copies, unless they use another validation library.

What parts need to be changed?

Most of these services with the exception of the builder.js and somewhat schemaForm.js should be very easy. Take Select.js for example, the only ting that ties it into Angular it's it dependency injection of sfPath and the wrapping code that makes it a service. I suggest that we use ES2015 modules instead of angular services.

Of course there will need to be wrapping code that wraps the ES2015 module in a service wrapper.

Small things

  • Change angular modules to ES2015 modules + wrapper, the latter not being in core.
  • Change any reference to angular. angular.isUndefined => foo === undefined, angular.isArray => Array.isArray, angular.forEach(foo, ...) => foo.forEach(...) or Object.keys(foo).forEach possibly with an if (foo) {} around it, etc.
  • Don't think we have any, but $q should be replaced with standard ES2015 Promise.

Bigger stuff

sfSchema.js and builder.js both are providers, so code needs to be moved around and though about a bit. Probably a good rule of thumb is to move configuration in provider to explicit arguments and try to keep the functions pure.

Testing

We have an opportunity here to simplify testing by testing it in node instead of in the browser, for instance with plain mocha tests. jsdom should probably be enough to test the builder.

Packaging

How should this all come together? Should it be in it's own git repo? I, davidlgj, have a suggestion:

  • Break it out the ES2015 modules into it's own repo, why not name it just schema-form?
  • Leave wrapping providers and factory functions in angular-schema-form
  • Use webpack to include schema-form into angular-schema-form so that the distributed files include core and doesn't need to included by the user as a separate dependency. This implies we need to upgrade angular-schema-form to ES2015 as well, but that shouldn't be a problem.

Other blue sky ideas

Just some thoughts on what we could do.

Futureproofing

So that ain't enough you say? You want it even more vanilla JS? We'll an argument could be made for making a version, with decorator and all, that is entirely in plain javascript without any framework. This has a couple of advantages:

  • Support one codebase that can be used withing several frameworks.
  • Kind of futureproof, will probably work with the next framework that comes along.
  • Should be really fast to load. Our current on first load performance hog by far is angular trying to find all it's directives. The DOM is already there, so basically we just need to hook up some event handlers. We could listen to events that bubble up if we're smart about it and that would mean almost zero loading time. Already present data would need to be validated, but that is fast compared to directives.
  • In some places easier code. We have a lot of hairy code just to work with ng-model and how angular wants it when it's not the way we like to do it. Error messages for instance, and the validation cycle.
  • Probably easier to support custom validations.

The disadvantages being also quite large:

  • Current add-ons will not work unless we can make some kind of angular compatibility layer.
  • More code for input handling and events. We really need to think about browser support in that case.
  • Some things will be hard to keep in vanilla js without getting into dependencies of some kind, like the drag and drop of the arrays. But in that case we should strive to keep them small and optional.
  • Some form options are angular specific (ngModelOptions, $asyncValidators etc) and would not be supported, but maybe we could have the same functionality under different names.
  • Probably a lot of work to get functionality on par with angular version.

incremental dom

The builder today just builds a the DOM using ordinary HTML templates (that just happens to have angular code in them) and standard DOM manipulations. It would be possible to do a version that instead uses https://github.com/google/incremental-dom. This probably wouldn't speed up the initial rendering, but could be a real boon in re-rendering speed.

Coupled with a plain JS decorator maybe? The decorators templates would need to be written in something that compiles to incremental dom, like JSX or superviews.js, the latter being basically HTML seems like a good choice.