Reputation: 17480
I have an ember component which wraps a text field. When a user types I want to fire of a search action.
#search-box.js.coffee
App.SearchBoxComponent = Ember.Component.extend
classNames: ['form-group', 'has-feedback']
term: ""
placeholder: "Search"
actions:
search: ->
console.log "Searching..."
# search-box.emblem
= input type="text" value=term class="form-control" placeholder=placeholder keyUp="search"
This maintains the binding between value and term, but the keyUp event goes to the Ember Input component and does not bubble to the search-box component. If I drop the =
and instead use a standard HTML input, I get the action sent to the right component, but the binding breaks and I lose my search term.
What's the proper way to use an input with an action inside a component?
EDIT: Another approach
Trying to do it with JQuery, with the added difficulty of searching after a specified period of inactivity (a second, in this case):
App.SearchBoxComponent = Ember.Component.extend
classNames: ['form-group', 'has-feedback']
delay: 1000
didInsertElement: ->
$input = @$('input')
$input.on 'keyup', =>
clearTimeout(timer)
if $input.val
console.log this
timer = setTimeout(@_performSearch, @get('delay')
_performSearch: ->
console.log this
console.log "Searching for #{@get('q')}"
When _performSearch
is called, this
is now window
and has lost the context of the Ember class. I also tried making everything fat arrows to make absolutely sure no function changes the context of this
, but to no avail. It will work if I make an anonymous function inside of the setTimeout call, but not if I call a method on the ember object.
Upvotes: 0
Views: 983
Reputation: 6709
You could set up a jQuery mouse event in the didInsertElement
hook of the component:
App.SearchBoxComponent = Ember.Component.extend
classNames: ['form-group', 'has-feedback']
term: ""
placeholder: "Search"
didInsertElement: ->
@$('input').keyup =>
console.log 'Searching...'
Regarding your second approach, you can specify the context of the function by using Ember.run.later
. Note: you were also missing closing parentheses after your call to setTimeout
.
Replace
timer = setTimeout(@_performSearch, @get('delay'))
with
Ember.run.later(@,@_performSearch, @get('delay'))
Upvotes: 0
Reputation: 2890
I've implemented the same search mechanics by observing value of search_term
(term
in your code). I think you could try to do it that way. You need to set observer in App.SearchBoxComponent
, firing search
action from there, if !Em.Empty(this.get('term')
.
Upvotes: 0