@belgoros wrote:
I still can’t figure out how to implement and correctly use a component in case where you need the same form to create or edit a Post, for example? The most difficult part is still calling the right action depending on if it is a new Post (should create) or an existing one (should update). I found it to be so basic and frequent in use that it would be grateful it to be a part of the docs.
Here is Posts
new
template:#templates/posts/new.hbs {{#post-form post=model postAction=(action "savePost")}} <button type="submit" class="btn btn-success">Save</button> {{/post-form}}
So here is a component template:
#templates/components/post-form.hbs <form> <div class="form-row"> <div class="form-group col-sm-6"> <label for="title">Title</label> {{input type="text" class="form-control" value=post.title}} </div> </div> <div class="form-row"> <div class="form-group col-sm-6"> <label for="body">Text</label> {{textarea type="text" class="form-control" value=post.body}} </div> </div> <div class="form-row"> <div class="form-group col-sm-6"> {{#power-select-multiple options=tags selected=selectedTags searchField="label" placeholder="Select some tags..." onchange=(action "selectTag") as |tag| }} {{tag.label}} {{/power-select-multiple}} </div> </div> <div class="form-row"> <div class="form-group form-check col-sm-6"> {{input type="checkbox" name="archived" checked=post.archived}} <label class="form-check-label" for="published">Archived</label> </div> </div> {{yield}} </form>
Post form component JS file:
#components/post-form.js import Component from '@ember/component'; export default Component.extend({ tagName: '', submit(event) { event.preventDefault(); this.postAction(this.get('post')); } });
Here is posts/new route:
# routes/posts/new.js import Route from '@ember/routing/route'; export default Route.extend({ model() { return this.store.createRecord('post') }, actions: { async savePost() { var route = this; let controller = this.get('controller'); let post = route.modelFor(route.routeName); let selectedTags = controller.get('selectedTags'); post.set('tag_ids', selectedTags.mapBy('id')); await post.save(); this.transitionTo('posts'); } } });
And finally,
posts/new
controller:#controllers/posts/new.js import Controller from '@ember/controller'; import { A } from '@ember/array'; import EmberObject from '@ember/object'; export default Controller.extend({ init() { this._super(...arguments); this.selectedTags = []; this.tags = this._dummyTags(); }, actions: { selectTag(tags) { this.set('selectedTags', A(tags)); }, savePost() { } }, _dummyTags() { let foot = EmberObject.create({ id: 11, label: 'Football' }); let voley = EmberObject.create({ id: 12, label: 'Voleyball' }); let handball = EmberObject.create({ id: 13, label: 'Handball' }); let tags = [foot, voley, handball] return tags; } });
It DOES not work, compilation errors, etc. What is wrong with all that ? What I’d like is just to reuse the same component for creating or editing a Post.
Posts: 1
Participants: 1