I have a component that will have a set of states, in which each state has a set of UI events and response methods. Some of the UI events may not be included in all the states.
My current idea is to create a controller interface including methods for each possible UI event that the component can then call in response to each event. Each state will then have a corresponding implementation of the interface. The main issue here is that many of the concrete controllers will have empty methods being called.
To avoid this issue, the only solution I can think of is to not even use Angular directives and have each concrete controller create its own event listeners. While this would avoid the previous issue, I am wondering whether there's a better approach relying on Angular features.
Related
i have an SPA designed using features (collection of components).. each component exposes bindable properties and some observable properties for inner state management.. the feature at the top level also exposes bindable properties that are used in implementation views to render out specific funcitonalities.. each feature has data dependencies that pull from APIs and some features depend on each other for values that are bound after data loads...
the problem - how do I best handle app initialization when there's changed events firing from observable/bindable properties all through that initial load. my first thought is to find a way to disable all observable in a single place in code that i then turn on once everythign is loaded and ready to start reacting to cascading changes... does that exist in some low-level aurelia API? the only other alternative is to carefully and tediously map out all dependencies and sprinkle "if(!isInitialized) then exit" statements everywhere but that sounds horrible...
That really depends on when you hydrate your components.
The docs here: http://aurelia.io/docs/fundamentals/components#the-component-lifecycle say that if you do something to properties in bind() lifecycle handler - the change handlers would not be called.
I have a hot RxJS Observable that I want to respond to in different ways depending on the context of the application. The Subject emits a new event based on some global action intercepted by a directive, but then I want
If a child component is subscribing to the Subject, then the child should handle the event
Otherwise, use a global handler
I can get the number of subscribers from the Subject and then tell the global handler to ignore if there are multiple subscribers, but it's not part of the API, so it seems like it may not be the right way to handle it. So what is the right way to do this?
Also, should the global event handler be part of the directive, the service, or should that be in a new component?
You can put global event subject in a global app.service and inject it in other component for subscription.
Although the ideal component should just have its own service maybe to handle complex event, but sometimes I feel directly inject a global service keeps the code cleaner. Otherwise, if you really want complete isolation or the component should be widely reusable e.g UI dropdown list, I suggest to use #Output to fire events (btw angular EventEmitter inherit Subject) and #Input to take in variables.
I am new to Javascript and AngularJS. Both seem to me as an event listener. What are the differences? Can I use them interchangeably? How?
$scope.$on will catch events that are.$broadcast() on the $scope whereas addEventListener listens to any events on the page. They're similar but not interchangeable.
If working in an angular app, I would definitely use $scope.$on unless otherwise needed, i.e. catching events from outside of the angular app. You will gain testability if you're writing unit tests and will only be looking for events from your own code, which is probably what you're looking for.
No. They operate on different objects, and are not interchangeable, although they are very similar in what they do. Both add an event listener to an object which can emit events, but scopes are not HTMLElements (like document), and different events are fired on scopes than on HTMLElements.
$scope.$on should be used wherever possible. Usually if there is an Angular way to do something, you should do it that way.
$scope.$on is used in conjunction with $scope.$emit which sends data to all parent controllers, and $scope.$broadcast which sends data to all child controllers. This gives you greater control over the flow of data through the app. Furthermore, handling events inside of a native event listener will break 2-way data binding.
I am quite experienced with JS and Backbone, but want your help brainstorming a best practise solution to the following problem:
There are two views. They sit side-by-side running concurrently in the page.
Both of these views are passed the same instance of a model.
Both of these views have actions which can update the model.
How, using Backbone's event driven programming, do you think would be the best way of distinguishing the events fired from view to view.
A possible scenario could be:
The user performs an action which updates the model in an invalid way on View A. But as the user did not perform it on View B they should not be notified there.
You can use intermediary objects to manage the flow between a repository (the object where the connection to the database takes place) and the instantiation / manipulation of views.
Instead of binding a model to a view from within the view, you can let the intermediary object (general purpose controller) make verifications, if required manipulations, before re-rendering the view with the modified model or collection.
Through the use of an event aggregator, you can trigger events from views from within the view, and listen to the event from within the "controller" object, who will in turn perform the required custom actions.
Using custom events seems simple enough. Just treat each view's actions as if they were different and name the events differently for each view (example this.trigger('view1:event1'), this.trigger('view2:event2')).
Make sure the views are subscribed to these specific custom events to avoid collisions on actions that would trigger events on both views (like attribute updates).
The following is from an issue I posted on EmberJS GitHub, but Stack Overflow is better suited for a discussion than GitHub.
I am building a few complex components at the moment including composite components and I hit a roadblock with the extreme isolation components live in.
There are several cases where I don't need the components to trigger an action on a controller, but where a controller needs to trigger a behaviour change on the component.
Problems is that the components don't know about the controller and the controller is not creating the components either: they are defined in a template.
I kind of solved the problem by subclassing the Ember.Component class to offer a way for messages to get through components.
The new component subclass breaks the on purpose isolation of components that shouldn't know about the outer controller.
The 2 less invasive options I found to make component methods calls from outside are:
Cache component / name of instance pairs in a global array like
App.components, then call a component method with
App.components['name'].method()
Trigger events from outside, register and handle them in the
components. However in that case I am passing an eventSource object
to the component, often a controller like so: {{my-component
eventSource=controller}}
My question is about how could we solve this problem in the most elegant and less invasive way possible for components ?
For achieving composite components, using the components like lego pieces, it seems impossible to me at the moment to see how we can achieve that goal without breaking the components isolation.
Any input, ideas, solutions, discussion is very welcome.
Note: By the way, the first method that breaks the component isolation is inspired by the work done on the ember-bootstrap components: https://github.com/ember-addons/bootstrap-for-ember
The author had to solve the same problem of being capable of triggering methods inside the components from outside.
Another note: Just for the record, another way to access a component is to use Ember.View.views['name'] where name is a view name you gave to your component. However I feel dirty to make such calls, even more from a controller.
In general, I would try to solve this by binding properties to your component, which could then change according to computed properties or observers based on those properties.
For instance, instead of trying to call a method like deactivate on a component, bind a property such as active to a property in the template:
{{my-component active=formEnabled}}
I'm hesitant to recommend passing an eventSource to components as a general solution (like your {{my-component eventSource=controller}} example). I imagine this could work with a class or mixin that just emits specific events and is tightly coupled with your component, but I'm struggling to come up with a use case that justifies this approach.