There are still some nuances I'd like to discuss with respect to the state of the UI and the state of scope variables in the controller.
Take ngShow for example. From the controller, you flip the state one way or another, and the DOM reflects that state. Like, $scope.isShown = true/false; the element is either given style={ display: none; } or not. But it is a one way street. If I were to change the class of my element to not be visible, I don't expect my $scope.isShown variable to be updated. And I think that's ok. Decisions to show and hide stuff emanate from the controller. It fits.
Suppose we use the same strategy for ngFocus, i.e. the DOM has a state that is representative of a scope variable. Ok, so we $watch our scope variable, and when it changes to "true", we change our DOM. But we (the controller) aren't the only ones who can change focus state, unlike the ngShow example. Tabbing and clicks cause the UI the change state. We now have to track blur events so that we can reset the scope variable to "false". Otherwise an assignment of "true" to a variable that is already "true" will never trigger the $watch. Ok, this turns out to work pretty good for ngFocus and ngBlur. We have a sort of two-way binding on our variable, and the state of that variable tracks the current focus state of the DOM element. Note that we required this two-way binding so that a variable can be changed again and actually trigger the $watch. I only reiterate this because of select().
What about select()? If I were to call select() directly on a DOM input element, it selects the entire text. This is a very specific reaction by the DOM. I might register an 'select' event listener to know when bits of text are selected. But how do I represent the state of a "select" in my scope variable? When should it be true, when is it false? Regardless of the element's state (whether the element doesn't have focus, does have focus, has a substring selected, has no string selected, whole string selected) a call to select() should have the specific outcome of selecting all the text. This means that a $watch for select needs to be able to fire *any* time I change its value. That implies that I should reset the value to false immediately after $watch detects its change to true.
In the case of select, the state of the scope variable can't really be made to represent the state of the UI. Select is a transition. Actually, so are focus and blur. But we can overload the word "focus" to mean both the transition (please set the focus) and the state (the element is presently focused). We cannot overload the meaning with select. Which seems to make a function call more suitable rather than a state assignment. Which then begs the question for all of them, for consistency.
We also have an initialization problem. If we are to treat our focus and blur scope variables such that they are representative of what is present in the UI, then to my knowledge, there is not a way to inquire the current focus state of an element. So we can't assign an initial value to the scope variable that reflects whether or not the element is focused.
This is how I arrived at thinking of focus(), blur() and select() as "triggers" rather than "states". I am not arguing for "triggers" rather than "states" or vice versa, but rather airing the issues. Blame it all on select().
Broc
On Wednesday, February 13, 2013 3:18:11 AM UTC-5, Joshua Miller wrote: