I just started learning ember today. (Trying to do yoember.com) tutorial. Please excuse my newbie questions.
I'm experiencing some issues and I am not sure what I am doing wrong.
Issue:
- Disabled does not work (it always enables the button)
What I am doing:
- I have a contact page which has email, message and submit button.
- I want to disable the button initially (When there is no email, message)
This is what I've done so far:
contact.hbs:
<h1>Contact Page</h1>
<form>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
{{input type="email" value=emailAddress class="form-control" placeholder="Please type your e-mail address." autofocus="autofocus"}}
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="text">Text</label>
<textarea type="textarea" class="form-control" id="text" placeholder="Text" rows="4" cols="50" value={{message}}></textarea>
</div>
<button disabled={{isDisabled}} {{action 'submitButton'}} type="submit" class="btn btn-primary">Submit</button>
</form>
Contact.js
import Route from '@ember/routing/route';
import { match, not } from '@ember/object/computed';
export default Route.extend({
emailAddress: '',
message: '',
isValid: match('emailAddress', /^.+@.+\..+$/),
isDisabled: not('isValid'),
actions: {
submitButton () {
alert(`Saving of the following email address is in progress:`);
}
}
});
Questions:
1) What am I doing wrong? Why is the button always enabled?
2) What is the difference when I do value=emailAddress
vs value={{emailAddress}}
1) What am I doing wrong? Why is the button always enabled?
You can't bind properties of a route directly to a route's template in ember. You must use a route's controller therefore. Controllers are singletons just like routes. So this shouldn't be an issue.
It's also not recommended to use actions others than for loading and error state on routes. They should also be moved to the controller.
Routes should be limited to serializing and deserializing the application state. This is important if you face the need for code-splitting per route. Please refer to the discussion about the route actions RFC for details.
Since you are not using any route specific stuff in app/routes/contact.js
route, you could just move that one to app/controllers/contact.js
and change it's base class from @ember/routing/route
to @ember/controller
.
2) What is the difference when I do value=emailAddress vs value={{emailAddress}}
As a general rule you can't have curly braces inside curly braces. So {{input value={{emailAdress}} placeholder="Please type your e-mail address."}}
won't be valid syntax.
Other than that the meaning depends on the context:
If using value=emailAddress
inside of a component invoked by curly braces, it refers the the value emailAddress
. This one might be a local variable defined by template scope (e.g. using let
helper) or a property of the controller / component. If it's a component template, the property might even be passed by invoking the component.
To avoid that confusion Ember introduced a new component invocation syntax. It uses angle brackets and allows to use curly braces inside to refer to variables. In that case <Input value=emailAddress />
would be invalid syntax as the value must be either a variable and therefore having curly braces or a string. So in that case only <Input value={{emailAddress}} />
would be valid syntax. Please also not that for this invocation syntax there is a difference between @value={{emailAddress}}
which passes emailAddress
to the component as an argument or value={{emailAddress}}
which binds emailAddress
to the HTML attribute value
defined by the components element.
Please have a look in the Ember Guides for details on this different component invocation syntaxes.
There are some other contexts but I guess from the question that it's about component invocation and this answer is already quite long.