Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: can-element + can-observe [+ can-jsx] #37

Open
phillipskevin opened this issue Oct 6, 2017 · 5 comments

Comments

Projects
None yet
4 participants
@phillipskevin
Copy link

commented Oct 6, 2017

I think a version of can-element that combines Custom Elements with can-observe for observable data and (maybe optionally) can-jsx for templating is really compelling.

This was discussed on a recent live stream (11:32).

I think not requiring the use of classes makes the API much simpler. Something like this is what I'm proposing:

import element from 'can-element';
import { h } from 'can-jsx';

element({
  tag: 'my-cool-element',

  data: {
    first: 'Kevin',
    last: 'Phillips',
    get fullName() {
        return `${this.first} ${this.last}`;
    }
  },

  view() {
    return (
      <input type="text" value:bind="this.first">
      <input type="text" value:bind="this.last">
      <p>Hello, { this.fullName }!</p>
    );
  }
});

Internally, the data would be wrapped in can-observe and the view would be wrapped in the can-jsx render function. (We could also make this work with stache, but with jsx we'd want to wrap it like this)

I think this would be very easy for newcomers to understand since they just need to define their element in js and add it to the html.

@justinbmeyer used the selling point at the last DoneJS Chicago that CanJS apps are data + templates and this makes it very easy to set that up without jumping through hoops.

@phillipskevin phillipskevin changed the title Proposal: can-element + can-observe + can-jsx Proposal: can-element + can-observe [+ can-jsx] Oct 13, 2017

@phillipskevin

This comment has been minimized.

Copy link
Author

commented Oct 13, 2017

@bmomberger-bitovi mentioned that maybe people would try to do

const data = {
  first: 'Kevin',
  last: 'Phillips',
  get fullName() {
      return `${this.first} ${this.last}`;
  }
};


element({
  tag: 'my-cool-element',

  data: data,

  view() {
    return (
      <input type="text" value:bind="this.first">
      <input type="text" value:bind="this.last">
      <p>Hello, { this.fullName }!</p>
    );
  }
});

data.first = "Brad";

Which would not work.

@phillipskevin

This comment has been minimized.

Copy link
Author

commented Oct 27, 2017

@justinbmeyer convinced me that we will also need events: {} so that we can make events and values work together. This will be needed for interoperating with third-party code, but also so that an element can trigger an event and also listen to it.

We may not need to use this very often in guides, but we probably should make it work.

@justinbmeyer

This comment has been minimized.

Copy link

commented Nov 1, 2017

@phillipskevin Why wouldn't that work?

If someone gives us a POJO object, I think we should just canObserve( Object.create(object) )

@bmomberger-bitovi

This comment has been minimized.

Copy link
Contributor

commented Nov 1, 2017

Observes can't dirty-check the underlying data. If you have:

var a = {};
var o = observe(a);
o[@@can.onKeyValue] = function(newVal) { console.log(newVal) };
a.foo = "bar";

the key value handler doesn't fire because o is not notified that a has changed.

I think new users will still find that confusing; maybe less confusing than the current way but still confusing. We should consider freezing objects that are passed in to can-element as data, at least in dev mode. That way it's clear that values can't be changed easily from the original prototype.

@matthewp

This comment has been minimized.

Copy link
Contributor

commented Nov 29, 2017

TodoMVC: #43

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.