If you haven't played around with
AngularJSyet, I highly advise you give it a try. There are plenty of introductory articles and videos out there that will whet your appetite and get you up and running (
here,
hereand
hereto name a few). Go ahead, go play. This post will still be here later when you need it. And you will need it.
Okay, for everyone else, after the excitement and wonderment of two-way binding begins to wane you will start to notice some of the peculiarities about AngularJS. And then after that you will start to wonder why it doesn't do some of the things you would expect to it to do (the simple answer is generally the great dev team working on AngularJS hasn't gotten around to it yet). I refer to these missing functionalities as missing directives. Which means we can write our own directives to add any desired functionality!
Lets jump in and take a look at form resets. If you have been developing for the web for any period of time you know that there is a native INPUT
element type that will reset all form input elements (including selects, textareas, etc.) to their original values. The following fiddle has a simple form that includes a native reset button and an Angular controller to initialize the model ("myModel").
Try editing the fields and hitting reset.
Wait. What happened? The expected behavior is for the form to reset the values of the input fields ('foo' and 'bar') to their original values ('Boop' and 'Beep' respectively). But as you can see this does not happen. What gives?
First, two underlying points:
Second, you might be wondering why this is how AngularJS behaves. I did and so at a recent AngularJS meetup I asked
Igor Minar, a core Google Angular developer, why it hadn't been implemented and he responded that the team just hadn't done it yet.
So, that leads to the question of what would be needed to make it work. Interestingly enough it's not a difficult thing to do once you have a firm understanding of AngularJS and its concept of directives. If you don't know what a directive is, this should be a good example.
Based on the points mentioned above, the directive would need to be:
Since directives can be attributes of an element, the directive can be an attribute of the form element itself similar to the
ngSubmitdirective. We then can use the attribute value to pass in the model for the form. This placement will also allow the capture of the native form reset event.
Lets preview with the finished directive before we dissect it. Once again, edit the form and hit the reset button.
Whew! It works.
If you notice on the HTML tab, the directive is invoked by applying an attribute to the form element with the value set to the model. The directive is then called and executes the returned function.
From the JavaScript tab we can see how the directive accomplishes our goals.
But first, some background on some of the key pieces used in the directive:
$parse
- since you can't pass the model object itself through the attribute (at least without creating an isolated scope), you can use this handy dandy service to get the model object from the attribute value stringangular.copy
- creates a deep copy of an object or an arrayscope.$apply
- executes the model assignment in an AngularJS context$setPristine
- used for setting the form to a 'pristine' state indicationWe can see the first thing the directive linking function does is to create a getter/setter for the passed model and then it creates a deep copy of this model. This deep copy will be the value that the model is reset to on any form reset events. Since
$parse
will only return an object with method
assign
if it is a model, we can use that to error check the input from the attribute.
The next step binds the custom reset handler to the native form reset event. When the native form reset event is fired, the custom reset handler prevents the default action (resetting the input elements to their non-existent value attributes), sets the model to the original copied state and finally updates the form state to indicate it is pristine.
That's it. That's all it takes. Nothing more. If you haven't realized it yet, while two-way binding is magical, directives are the building blocks of AngularJS.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4