-
-
Notifications
You must be signed in to change notification settings - Fork 406
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
hasBlock.js #102
hasBlock.js #102
Conversation
6e5c757
to
a93bc17
Compare
@shaunc @BryanCrotaz pinging you here as you're currently building the whackiest components I'm aware of - is this an issue you've come across? |
Ooh nice. Yes please. Any component that has default behaviour that can be overridden by a block would find this useful. |
@BryanCrotaz The question is what can you do with hasBlock.js that you can't do with {{#if hasBlock}}? |
We are in fact using |
We could make has-block a subexpression instead and it would be more consistent. I agree we should strive to keep template context === the actual context. |
I am persuaded by the argument that a block is as much a part of the public interface of a component as attributes are, and we already bundle up a snapshot of the attributes in {{#my-each items as |item index|}}
{{index}}: {{item.name}}
{{else}}
No items :'(
{{/my-each}} // components/my-each.js
export default Ember.Component.extend({
init() {
console.log(this.blocks);
/* Logs:
{
default: { arity: 2 },
inverse: { arity: 0 }
}
*/
}
}); |
This looks great... (very similar to what functionality We've tried to support in ember-declarative); however:
Where this would be the layout for a template:
Here the idea is that the The |
i am curious about the necessity for this? if a component is yielded as a block should we have the ability to compute properties from that status, potentially changing what the component actually does if it is a block or not? should a component be allowed to do completely different thing if it is rendered as a block vs. not? i think that is the possibility that is ultimately being opened up here. |
@grapho I read that you're asking for real use cases. Here is mine: I basically want to understand if I need to create a 3rd party popup or not. I made the component's block to be the popup's content. That was a design decision. This is probably an edge case, but there other different and more common cases. It all depends on what your component semantics are. Here I assumed that the block of my component is the popup content. Similarly, other components semantics may require different stylings depending on |
a93bc17
to
bb7c461
Compare
any chance of this coming back into focus? |
@ksnyde can you add your use case? |
I'm using it for my This is the most recent use-cases (aka, today) where I've wanted this but it's come up several times in the past. |
Use Case 1 Similar to those listed in emberjs/ember.js#11741: Need the ability to set a class depending on the presence of a block or not on the root element. Use Case 2 Am developing a component to display error messages associated with the validation of form elements. If there is a string assigned to the error object for the property specified, then that error message is displayed. For example:
Given a string assigned to the error object for the property specified it is also possible to provide your own error message rather than the one from the string:
This latter behavior can also work with this setup
where the indication that there is an error, through the use of But in this scenario, the first component usage listed - EDIT: Regarding my last paragraph the determination of the value is a computed property in the component and I need to make this decision in the component, not in the template. |
We actively ensured that In the future it's likely that the best solution emulates the Web Components "slots" proposal and remains completely declarative inside of the template. It is unlikely that we expose whether or not the component is simply invoked as a block as that interim step sets up more complicated migration paths for people to the more-idyllic solution. |
@nathanhammond The template-only solution is only viable if you can wait until after the template has been rendered to make use of the set property in the component, such as in a computed property. If you want to use the knowledge of whether the component is being used in block or non-block form in |
@notmessenger Confirm, but we don't want the layout to result in conditional changes to how something is loaded. We intentionally want information flow to be unidirectional, making it bidirectional results in lots of complexity and makes it far more difficult to understand what is happening inside of the template. Your example in your previous post can certainly be implemented using (Yes, we can come up with contrived examples that do all sorts of weird things in By splitting up or nesting or generally refactoring components I believe we can achieve all of the desired behavior. |
@nathanhammond this thread going "crickets" doesn't make me not want this any less. 😞 I still need to use this hack: https://github.com/miguelcobain/ember-leaflet/blob/master/addon/mixins/popup.js#L17-L24 That case isn't trivial to implement with |
And most of the activity on emberjs/ember.js#11741 occurred before this PR even existed. |
@miguelcobain I appreciate how you're striving for an incredibly clean UI for consumers of I'd encourage us to look toward that as the direction we want to take this. @miguelcobain and @notmessenger if you'd like to work toward a slot-based proposal I think that would be something the Ember core team would be receptive to, but you should check pulse in #dev-ember first. |
@miguelcobain You're right that that is very confusing. It was an accident to use the syntax |
I think most use-cases will be covered by Glimmer component. The new Glimmer component will have a more declarative way of handling the root element that will remove the need for classNameBindings/attributeBindings/etc. Since there is a pretty good, albeit ugly, workaround for many cases (https://github.com/miguelcobain/ember-leaflet/blob/master/addon/mixins/popup.js#L17-L24) we are prioritizing on pushing Glimmer component to completion and teaching only the template helper version of |
An |
Having |
FWIW - Ember 2.9+ will have |
@rwjblue is the implementation accessible from within the component itself or only templates? |
@bcardarella - Templates only |
@rwjblue is there a plan to provide a public API for components to determine if a block has been passed? |
More fuel for the discussion, my use case: I am using an external framework (clipboard.js) and attempting to integrate it into my component. The framework requires a |
Yet another use case, in which I'd actually like access to whether an inverse block was provided: I've got a typeahead component and I'd like to allow consumers to provide markup for the typeahead dropdown's "default" state (when the input is focused but nothing is being searched): {{#ui-typeahead as |suggestions|}}
{{#if suggestions}}
{{! Suggestion Template }}
{{else}}
No results.
{{/if}}
{{else}}
This is the default state.
{{/ui-typeahead}} In this case, if an inverse block is provided, I'd actually like to change the behavior of the component. The typeahead would show it’s dropdown with the default state rendered inside when the input is focused—instead of only when there are suggestions to display. (The behavior would be similar to this example.) {{! ui-typeahead.hbs }}
...
{{#if shouldShowDropdown}}
<div class="typeahead-dropdown">
{{#if searchTerm}}
{{yield suggestions}}
{{else if (hasBlock "inverse")}}
{{yield to="inverse"}}
{{/if}}
</div>
{{/if}} While a |
I'll share my use case:
would really like to move that complex logic into a computed property in my js file |
+1 for @atomkirk's use case. It's a lot easier to unit test a complex computed property like that than having to step into an integration test. Not having a This RFC is naturally going to gather (less) attention which is proportionate to the number of people authoring add-ons and writing integrations in the community. These are still valid use cases. |
I would like to access My component extends My component can be called as a block or inline component, but the link title is set by my component rather than the user. This is problematic for me, because if the user uses my component inline, the route gets set as the link title and routing breaks but if they use my component as a block, routing works fine. Being able to do the following would solve my issue:
The |
still no |
This has been superseded by the Named Blocks RFC; you'll be able to check the falsiness of blocks passed in as properties to know whether a block was passed in, so there's no separate need for a hasBlock.js. |
Rendered
Please let me know of any other use cases for
hasBlock
in js land.Also, please let me know of any drawbacks you can think of.
/cc @alexspeller @rwjblue