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: Rapid Prototyping with Scaffolding #1050

Open
justinbmeyer opened this Issue Nov 3, 2017 · 4 comments

Comments

Projects
None yet
3 participants
@justinbmeyer
Copy link
Contributor

justinbmeyer commented Nov 3, 2017

tldr; Create some custom elements that help prototype Creating, Updating, Reading, and Deleting (CRUD) model and other observable data. This will make both bootstrapping an application and creating demo pages easier.

Related Proposal: generate bidirectionally bound html form from map

This was discussed on a recent live stream (21:08). If you haven't watched the live stream, watch the live stream. The live stream does the best job of explaining this proposal.

Proposal

We propose 5 components:

  • <can-create Type:from="key"> - A form that will create instances of Type.
  • <can-edit data:from="key" Type:from="key"> - A form that edits data.
  • <can-list data:from="key" Type:from="key"> - A list view that shows the items in list or loads the list of data from a can-connected Type.
  • <can-view data:from="key"> - A view that shows a single item's data.
  • <can-crud Type:from="key"> - A view that builds all the preceding utilities and makes them work together. (I am not sure how I feel about crud not lining up with the other names)

And we propose the following methods for extracting information about an object or Type:

canReflect.getOwnKeyDescriptor

This would work just like Object.getOwnPropertyDescriptor, but include a type property:

canReflect.getOwnKeyDescriptor(object, key) //->
{
  get, set, value, writable, configurable, enumerable,
  type
}

The type property would be used to know how to display or create a form for the particular property.

canReflect.getOwnKeyDescriptor

This would work just like Object.getOwnPropertyDescriptor, but include a type property:

canReflect.getOwnKeyDescriptor(object, key) //->
{
  get, set, value, writable, configurable, enumerable,
  type, 
}

The type property would be used to know how to display or create a form for the particular property.

NOTE: It might be useful to include the ability to see if this value is producing an error.

canReflect.getInstanceKeyDescriptor(Type, key)

Returns the key descriptor for an instance of type Type's key.

Person = DefineMap.extend({
  first: String,
  last: String,
  get fullName(){ ... }
});

canReflect.getInstanceKeyDescriptor(Person, "first") //-> 
{
  get: function(){ ... }, 
  set: function(){ ... }, 
  writable: true, 
  configurable: true, 
  enumerable: true,
  type: String
}

canReflect.getInstanceKeyDescriptor(Person, "fullName") //-> 
{
  get: function(){ ... }, 
  set: function(){ ... }, 
  writable: true, 
  configurable: true, 
  enumerable: false,
  type: String
}

canReflect.getInstanceKeys(Type)

Returns the possible keys for instances of this Type.

Person = DefineMap.extend({
  first: String,
  last: String,
  get fullName(){ ... }
});

// notice that fullName is returned.  
// It's not enumerable, so we wouldn't build a control for it.
canReflect.getInstanceKeys(Person) //-> ["first","last", "fullName"]

Use

Creating a demo page

Say we have the following <my-component> that contains a ViewModel with a Date, Number and String type:

ViewModel =  DefineMap.extend({
  dueDate: Date,
  age: Number,
  name: String
})

Component.extend({
  tag: "my-component",
  ViewModel: ViewModel
})

We could use <can-edit> to create a form that would be able to adjust the
properties of the component's viewModel instance as follows:

<my-component this:to="scope.vars.myComponentVM"/>
<can-edit data:from="scope.vars.myComponentVM"/>

<can-edit> would produce 3 controls, each of which would be able to display and update the values on myComponentVM. The output of <can-edit> might look like:

<form>
  <label>dueDate: Fri Nov 03 2017 10:40:00 GMT-0500 (CDT)</label>
  <input type="datetime-local" value="11/03/2017 10:40 AM">
  <label>age: 35</label>
  <input type="number" value="35">
  <label>name: Alfredo</label>
  <input type="text" value="Alfredo">
  <input type="submit"> <input type="reset">
</form>

Bootstrapping/Scaffolding application development

If a user has a simple connected model like:

Todo = DefineMap.extend({
  id: Number,
  complete: Boolean,
  name: String
})

connect.baseMap({
  Map: Todo,
  service: new Service({id: "id"})
})

By adding <can-crud Type:from="Todo"> in the page, a user should be able to:

  • create a todo
  • list all todos
  • select a todo to edit in the list and update that todo
  • select a todo to delete in the list

<can-crud>'s template would look like:

<h2>{{plural Type.name}}</h2>
<can-list Type:from="Type" on:editing="showEdit()"/>

<h3>Create {{Type.name}}</h3>
<can-create Type:from="Type"/>

{{#if isEditing}}
  <maybe-a-modal>
    <can-edit data:from="editing"/>
  </maybe-a-modal>
{{/if}}

<can-list>'s template would look something like:

{{#each itemsPromise.value}}
  <tr>
     {{#eachDescriptorAndValueOf(this, des=descriptor, value=value)}}
       <td>{{value}}</td>
     {{/eachDescriptorAndValueOf}}
     <td>
       <button on:click="edit(this)">edit</button>
       <button on:click="destroy(this)">X</button>
     </td>
  </tr>
{{/each}}

Progressively enhancing

Ideally, <can-crud>'s behavior could be progressively enhanced with <can-slot>. For example, a
different from was desired for creation, <can-crud> could be called like:

<can-crud Type:from="Todo">
  <can-slot name="create"> <todo-create/> </can-slot>
</can-crud>

@justinbmeyer justinbmeyer referenced this issue Nov 3, 2017

Closed

Epoch 1 Survey Questions #77

24 of 24 tasks complete

@justinbmeyer justinbmeyer changed the title Proposal: Quick prototyping scaffolding for observables (in progress) Proposal: Quick prototyping scaffolding for observables Nov 3, 2017

@chasenlehara chasenlehara changed the title Proposal: Quick prototyping scaffolding for observables Proposal: Quick prototype scaffolding for observables Nov 3, 2017

@justinbmeyer

This comment has been minimized.

Copy link
Contributor Author

justinbmeyer commented Feb 6, 2018

<can-crud Type:from="Person">

    <can-template name="edit">
        <can-edit Type:from="Person">
            <can-template name="firstName">
                ENTER YOUR first name Please!!!!!
                <can-field Type:from="Person" key:from="firstName"/>
            </can-template>
        </can-edit>
    </can-template>

</can-crud>
@justinbmeyer

This comment has been minimized.

Copy link
Contributor Author

justinbmeyer commented Feb 18, 2018

@justinbmeyer justinbmeyer changed the title Proposal: Quick prototype scaffolding for observables Proposal: Rapid Prototyping with Scaffolding Apr 20, 2018

@roemhildtg

This comment has been minimized.

@matthewp

This comment has been minimized.

Copy link
Contributor

matthewp commented Nov 14, 2018

@justinbmeyer can this be closed? I believe can-crud is basically this.

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.