I'm using Ember 2.3 and have built a controller around Ember Highcharts. When a chart point is clicked I send that event back to the controller via the following nasty bit of code added to the highcharts configuration object:
Graph.__container__.lookup('controller:accounts.account.outlets.outlet.ratings').send('pointClick', event);
(I know this is fundamentally wrong and should be using getOwner.lookup for the container reference)
This works without issue, but I'm now refactoring this controller to a component and can't think how to pass the graph event back to the component as components are not registered in the app container.
Any pointers to how to achieve this would be very much appreciated!
Thanks.
UPDATE
I've just discovered that I can send an action to a component from the Highcharts event function:
Graph.__container__.lookup('component:ratingsGraph').send('pointClick', event)
But this seems to create a new instance of the component, rather than send to the existing instance. I guess that makes sense as components aren't singletons.
Very frustrating!
Some days you can't see the wood for the trees!
Instead of defining the highcharts event function in the highcharts configuration parameters, I simply defined it within the component and passed it to highcharts. This enabled me to use a closure to hold reference to the defining component.
Doh!
Related
I have a service which I call state that just handles loading states and I can expand it to whatever I may want in the future. I needed this service so I could have different components talk to each other in a way so they would know if another component is loading or doing something.
Anyway I have this button that I use in different places that just sends an action, and then turns into a spinner until that action is complete.
They way the loading animation works currently is classNameBindings: ['state.working'],
However if I now have two of these buttons on screen at the same time, and I call this.state.set('working',true); all the buttons are now spinning.
I would rather pass in a property name to the button component that tells it what property to watch on the state service to determine if it should add the working class or not
I'm just having some trouble figuring out how to make this work in the component.
How can I have the class binding watch for a dynamic property name that will be passed to the component as something like loadingPropertyName so each button component can watch a different property for it's working class binding.
You can do something like this:
init() {
this.set('classNameBindings', 'state.'+this.get('stateProp'));
this._super();
}
I have a component working pretty well and now I need to call it inside a controller.
Scenario: I have an ember application, and I have an update button controller, I did a component that just display a toast(Materializecss) with some message I pass as parameter to the component and both the button and the toast are working well separately. I need to call inside the button controller this component to display to the user if the update was successfully or not using this component I did. Any sugestion of how can I call this component inside the controller? Thanks
have a look at the ember-twiddle I created and see if it fits the bill, in regards to what you want to do ?
You should instead of thinking "calling the component", rather, how can I push updated attributes/data to the component.
Ember relies on the "Data Dow Actions Up" pattern. This implies that you cannot make an explicit call to a component action from a controller. (see https://dockyard.com/blog/2015/10/14/best-practices-data-down-actions-up for example)
Instead, a better design should be to define a service to manage data : messages to be "toasted". Then make this service available by injecting in in your controller. You will be able to call methods to register a new messages and generate new data.
Provide also a component template (to be included in your own templates) that will be in charge to display the new message, etc. Each change in the data managed by the service will lead to a component template update.
You should definitely take a look to https://www.npmjs.com/package/ember-toastr
I am wondering what is the best way to control behaviour on a component.
In my case I have a {{stop-watch}} component.
I want to start, stop and reset the component via the routes using the {{stop-watch}} in their template. The start and reset function should allow me to somehow pass the number of seconds to run for.
How can this be done when a component only really supports bindings and not the ability to execute behaviour?
This is the only way I can think of doing it. In this case; isStarted,isStopped and isReset would be boolean variables and I would toggle them to control the component.
{{stop-watch start=isStarted stop=isStopped reset=isReset timeout=timoutSeconds}}
Toggle like this for each property binding in the controller
this.set('isStarted', !this.get('isStarted'));
Observe like this for each property in the component
startUpdated : function() {
//start the timer
}.property('start')
In my opinion the above solution is very inelegant and verbose and there must be a better way to achieve this.
Are the any best practices for this scenario?
You should have a model that possesses a state and methods to control the state.
You set up an instance of the model in the route, then you'll be able to control it both in the controller and the stop-watch component.
The component will automatically update its looks based on the properties of the model, and will be able to call methods on the model via actions on the component.
how to refresh List View dynamic data content in android?
I tried loading dynamic data for the List View in android application but no luck .Any advice how to accomplish this?
Call notifyDataSetChanged() on your Adapter object once you've modified the data in that adapter.
Some additional specifics on how/when to call notifyDataSetChanged() can be viewed in this Google I/O video.
Or else Look at this link.it may helpful.
Dynamic ListView in Android app
Or else
The right thing to do is to call notifyDataSetChanged() on your Adapter.
Troubleshooting
If calling notifyDataSetChanged() doesn't work all the layout methods won't help either. Believe me the list view was properly updated. If you fail to find the difference you need to check where the data in your adapter comes from.
If this is just a collection you're keeping in memory check that you actually deleted the item from the collection before calling the notifyDataSetChanged().
If you're working with a database or service backend you'll have to call the method to retrieve the information again (or manipulate the in memory data) before calling the notifyDataSetChanged().
The thing is this notifyDataSetChanged only works if the dataset has changed. So that is the place to look if you don't find changes coming through. Debug if needed.
UI Thread
It is true that this has to be called from the UI thread. Other answers have examples on how to achieve this. However this is only required if you're working on this information from outside the UI thread. That is from a service or a non UI thread. In simple cases you'll be updating your data from a button click or another activity/fragment. So still within the UI thread. No need to always pop that runOnUiTrhead in.
More Information
Another nice post about the power of list Views is found here:http://www.vogella.com/articles/AndroidListView/article.html
The new ember router has been throwing me for a loop. Does anyone know how to manually triggering a url change when you are (1) NOT using a redirect in the router (2) NOT using the linkTo helper?
It seems that this:
App.container.lookup('router:main').router
no longer works, as of today's build.
This seems hard to do in new ember router because ember is working hard to prevent you writing code in this style. Rather than access an instance of the router (or anything else) via App your ember application code should be working with properties that have been injected at runtime by the framework. As #sly7_7 mentioned above, your view will have access to the controller and controller can trigger a transition like:
view.get('controller').transitionTo('state')
Depending on how your third party library is working, you might do this by triggering an event in the dom (handled by the view) or by registering a callback when the view is rendered from within didInsertElement
The main thing to remember is that App.anything-in-lowercase is generally bad practice. Whenever possible try to let the framework take care of instantiating and wiring together your application classes.
For more detail, see the notes on this commit: https://github.com/emberjs/ember.js/commit/5becdc4467573f80a5c5dbb51d97c6b9239714a8
You can try this:
App.__container__.lookup('router:main').transitionTo('name_of_your_route');