I'd like to be able to monitor dom.window.location.hash for changes (hopefully in an event-oriented fashion, as opposed to polling). Is there a way to do this with the API.
Sure -- you just hook the "hashchange" event, same as in JavaScript. Here's an example, from my own code.
Related
In the everyday front-end development I often use DOM as a global event bus that is accessible to every part of my client-side application.
But there is one "feature" in it, that can be considered harmful, in my opinion: any listener can prevent propagation of an event emitted via this "bus".
So, I'm wondering, when this feature can be helpful. Is it wise to allow one listener to "disable" all the other? What if that listener does not have all information needed to make right decision about such action?
Upd
This is not a question about "what is bubbling and capturing", or "how Event.stopPropagation actually works".
This is question about "Is this good solution, to allow any subscriber to affect an event flow"?
We need (I am talking about current usage in JS) stopPropagation() when we want to prevent listeners to interfere with each other. However, it is not mandatory to do so.
Actual reasons to avoid stopPropagation:
Using it usually means that you are aware of code waiting for the same event, and interfering with what the current listener does. If it is the case, then there may (see below) be a design problem here. We try to avoid managing a single thing at multiple different places.
There may be other listeners waiting for the same type of event, while not interfering with what the current listener does. In this case, stopPropagation() may become a problem.
But let's say that you put a magic listener on a container-element, fired on every click to perform some magic. The magic listener only knows about magic, not about the document (at least not before its magic). It does one thing. In this case, it is a good design choice to leave it knowing only magic.
If one day you need to prevent clicks in a particular zone from firing this magic, as it is bad to expose document-specific distinctions to the magic listener, then it is wise to prevent propagation elsewhere.
An even better solution though might be (I think) to have a single listener which decides if it needs to call the magic function or not, instead of the magic function being a stoppable listener. This way you keep a clean logic while exposing nothing.
To provide (I am talking about API design) a way for subscribers to affect the flow is not wrong; it depends on the needs behing this feature. It might be useful to the developers using it. For example, stopPropagation has been (and is) quite useful for lots of people.
Some systems implement a continueX method instead of stopX. In JavaScript, it is very useful when the callees may perform some asynchronous processing like an AJA* request. However, it is not appliable to the DOM, as the DOM needs results in time. I see stopPropagation as a clever design choice for the DOM API.
It's well known that you must manipulate DOM elements inside directives when using AngularJS.
However, it seems that, in some use cases, manipulating DOM inside a service is acceptable.
Misko Hevery is talking about this here. You can also find an example within the Bootstrap UI Dialog.
Misko's explanation is rather vague so I was wondering how do you determine when you need to put DOM inside a service instead of a directive.
A directive, with the way it is defined, is always attached to a DOM node. So when you define a directive, it "expands" or replaces the DOM node to which it is attached.
In certain situations (like dialogs) you won't be able to attach DOM nodes to any specific parent. In these cases using a service makes sense and the controller can still stay out of the DOM bit because the DOM manipulation will be encapsulated in a service..
Popups could be another situation where we could probably use a service, but unlike a dialog, a popup IS attached to a DOM node. So, even that is slightly a grey area.
So, a basic and simple test is, "Can this bit of DOM Manipulation code be attached to a DOM node?" If yes, then directive. If no, then service.
Dialogs and Custom Confirm Boxes come in as typical examples where you would use a service.
Whilst I think Ganaraj has described what Misko was saying well, you could (and potentially should) argue that the DOM manipulation code for a modal dialogue (for example) can be put into a DOM node.
One approach is to have a dialog directive attached to the DOM the whole time, and then use ng-show to conditionally show it. You can then communicate with the modal dialog using either $rootScope, or better: a service.
I actually prefer this approach because it feels 'right' - the service handles the transfer of data and the directives interact with the service to make sure it gets displayed in a way that makes sense to the user.
But I think the fact that Misko is not particularly clear about it shows that it's quite subjective. Do what makes the most sense to you.
I'm googling this topic to reinforce my inner feeling about this because I'm working on an issue right now that makes me want to place certain logic in a service. Here's my case, and what I think is a plenty good justification for putting dom-based handling in service:
I have directive-based elements that react to mouse position, globally (e.g. they move or change in some way based off mouse position). There are an indeterminate number of these elements and they don't pertain to any specific location in the application (since it's a GUI element and can pertain to any container anywhere). If I were to adhere to the strict angular "dom logic in the directives only" rule, it'd be less efficient because the elements all share the logic pertaining to parsing the mouse position (efficiently) which revolves around window.requestAnimationFrame ticks.
Were I to bundle that logic into the directive, I'd have a listener/raf loop tied to every single instance. While it'd still be DRY, it wouldn't be efficient since on every move of the mouse you'd be firing the exact same listener that would return the exact same result for every single element.
It's actually best in this case to move this into a service, despite it being dom-based logic, and register each directive instance against the service to call the same, instance-based logic against the logic performed that would be duplicate for each instance.
Remember, while Angular provides some very good advice around how to structure you code, that does not make it bullet proof of by any means a hard and fast rule, since it can't possibly cover all use cases. If you see a hole where the "best practices" seem to fail, its because you're actually properly understanding the best practices, and you've now found a reason to break the rules on purpose.
That's just my 2 cents!!
I agree with #dudewad. At the end of the day a service (factory, provider, value) is just angular's module pattern with the limitation of being implemented as a singleton. I think it's important that you get access to the DOM via an element that is passed into a directive's link function and not by using document or other global approaches. However, I don't think that it's important that the logic that you apply to dom element that you get from a directive lives in the same module. For SRP reasons it can be favorable to break up the code a bit using a service as you might have a particularly complex piece of logic that it makes more sense to have focused test around or you might want to use the logic in more than one directive as pointed out by #dudewad.
one drawback to using a DOM manipulation method based off of changing a variable (ie, ng-show="isVisible") is that the DOM manipulation occurs after the next "javascript turn" loop (when isVisible is updated). You may need the DOM to be updated right away.
For example, a common scenario is displaying a "spinner" during transitions to a new route / state. If you were to set $scope.isVisible = true on the $routeChangeStart / $stateChangeStart event, and then $scope.isVisible = false on the $routeChangeSuccess / $stateChangeSuccess event, you will never see your ng-show, as the whole route / state change happens within one javascript turn. It would be better to use .show() and .hide() in those events so that you actually see the spinner.
to bring this all back and make it relevant to the OP's question -- in a situation where the DOM manipulation is a "spinner" modal being displayed, I would do it during the service, and I would do it with direct DOM manipulation methods, rather than relying on a model change.
When writing Swing or AWT applications, I'm aware that GUI changes should always be done in the EDT. How does this translate to writing GWT applications?
I'm looking at a scenario when I call the following.
myRequestBuilder.sendRequest(myRequestDate, myRequestCallback)
myRequestCallback modifies the GUI. Having such a construct in Swing, I would make sure that the myRequestCallback invokes the EDT for the GUI changes. Does GWT require me to do something similar as well?
On the web (in browsers), it's dead easy: everything always executes in the event dispatch thread.
See also http://www.html5rocks.com/en/tutorials/workers/basics/
I'm collaborating on a large Kynetx app with another developer. To make it easier to split up the work, I'd like to have multiple rulesets so we can work on them separately without stepping on each other's toes.
Is there a way to raise an event (explicit or otherwise) in another ruleset? Something like this in a postlude:
raise explicit event next_section in a163x50
I know it's possible to do with JavaScript in the browser, but I'd like to do this from the KRL on the server side.
You can raise events in the postlude, and you use with [appid] instead of in. Check out the Explicit Events section of the Postlude Documentation.
Here is an example postlude, raising an event to a new app with some context:
fired {
raise explicit event "something" for a163x50 with cheese = "swiss";
}
For a really complete walkthrough of loosely coupled rulesets, see Phil Windley's post called Tweeting from KBlog.
Don't forget about modules for code reuse. Wrapping functionality in a module makes it much easier to test that code, and enable use within multiple rulesets.
From what I understand, the entire client side of a GWT application is converted to Javascript when you build, therefore I suppose this question is related to both Javascript and the possibilities that GWT offers.
I have a couple of dozen processes that will need to be initiated in my GWT application, each process will then continuously make calls to a server. Does GWT support threading? Does the GWT client side support threading?
EDIT:
This link states:
No JavaScript knowledge required If you’re just a user of the framework,
which I am for the matter of discussion, you do not need to know JavaScript
in order to write dynamic content, be it client-side such as rolling frames,
docking panels or scheduled “multi-threading” tasks, or server-side calls
using XMLHttpRequests (aka AJAX).
or scheduled “multi-threading” tasks, what does this mean?
JavaScript doesn't support multithreading. However, GWT has a class to 'simulate' threading, which is not real multithreading, but in most cases does what you need: com.google.gwt.core.client.Scheduler.ScheduledCommand. The technique is based on the timer class, which executes a method after the given time elapses.
For example, when placing the following code in you own code, the scheduleDeferred method will return directly and your code continues after the command, while the execute() method is executed using the timer:
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
public void execute() {
.. code here is executed using the timer technique.
}
});
You can create a repeating command RepeatingCommand, which can be used to run the command more than once. Start it with Scheduler.get().scheduleIncremental() that will execute the command until the execute method returns false. You can use this to split tasks into sub tasks to get better 'threading' behavior. The Scheduler supports some additional methods to start a scheduled command differently. See the JavaDoc for more details.
Edited and updated with new GWT class instead of the deprecated DeferredCommand.
There is work on Web Workers as part of HTML5 that is implemented in a number of browsers, but not on all (most notably internet explorer). You could use these features where available, but what you should do is look at the javascript programming model.
Javascript generally works asynchronously. Requests are fired off and at some point their answers are received as an event. You can have a large number of pending requests at the same time. This will require a bit of a redesign of your system though.
New way is to use a Scheduler
JavaScript doesn't support multithreading, so whatever GWT does, multithreading has to be done solely on the server side, because GWT can only use features that are already available on the client side.