This article mainly introduces the Angularjs tool Angular-smarty, which can automatically complete the UI, including the use of the isolation scope binding script and promise, which can be consulted by friends.
We have recently added an AutoComplete feature (called Smarty) to our forum, on the home page that requires a professional profile. This is a very useful feature because it helps us navigate the user to where they really want to go. It's interesting and it's built with Angularjs!
We hope that Smarty can:
Automatically provides recommendations through an HTTP request, with a user's given input (a prefix)
Display a suggested Drop-down list
Update when user enters
Fast enough to keep up with user input
Navigation intuitive and can be closed
Reusable
In the past there was no angularjs experience, and this project was a starter project I used for this framework. It really became a valuable learning experience, and I found that many aspects of the framework are good for each other and fit well with the requirements listed above. Of course, there are still some problems in the learning process!
The fun of Angularjs
One of my favorite angular is how it breaks down into concepts with a clear purpose. Two of these concepts--directives and Services are widely used in smarty. Directive and Dom are bound together to manage interactions with elements, and service provides independent reusable logic for controller and directive through dependency injection.
Angular offers a lot of built-in directive and service, and we've used many of them in this project.
To show the recommendations (see Request 2), we used the ngif and Ngrepeat directives to conditionally display and populate the suggested down list.
In order to update the proposed content when the user enters (see requirement 3), we use the ngmodel instruction to bind the request of the INPUT element on the $scope prefix variable to the $watch method on the scope to listen for the change of prefixes.
One thing we need to consider is that this automatic completion may not keep pace with the user's input speed (see request 4). Because the value of each current suffix changes, Smarty sends an HTTP request (via the built-in $http Service). We decided to cache the results with $http optional configuration parameters ($http. Get (Requesturl, {cache:true})). This is a very simple way to improve performance.
We have also written customized directive and service to meet our specific needs:
Smartysuggestor Service:smartysuggestor provides a getsmartysuggestions () function that accepts user-generated prefixes as its arguments. and access to our backend Suggestor services via HTTP requests for automated recommendations. (see request 1).
Smartyinput directive: One of the challenges we face is to define all the possible interactions between a user and a Drop-down list, and write test cases to ensure that these features are intact during and after development. We use a directive (Smartyinput) to contain all possible interactions between the user and the Drop-down list (see Request 6), while we use the built-in ng-mouseover and Ng-click directives (Directive) To define the interaction between the Drop-down list and the mouse event.
As I mentioned earlier, one of the challenges we face is to make sure that we do not destroy the possible interaction between all users and the dropdown list. To track these user interactions and make sure we didn't destroy it during development, we used the Jasmine test framework. Jasmine combined with this angular-mocks allows us to write a test case that contains a description for smarty, like we can write "Click outside should disappear" for the Drop-down list ("Should disappear on outside click"), You can write "the appropriate value to be filled in by carriage return" ("should, on enter, fill with the appropriate value") to request the form's input.
Learning Summary
Although the concise and practical ANGULARJS framework is now easy for me to read, it does take some time to learn. Isolating scoped binding directives and promise are two of the most difficult topics in my learning process. When I studied isolation scopes, I found myself looking forward to seeing more examples of how people use different bindings in their projects, so I give an example for each type of binding.
=: bidirectional data binding between local and parent scopes
Controller:
1$scope.selected =-1;
Html:
Smartyinput instruction Character:
1scope: {index: "=", ...}
The smartyinput bidirectional binding specifier binds the selected in the controller scope to the index index of the instruction scope, so that the results and instructions in the index index (the currently selected index in the proposed list) are changed (for example, the user presses the UP/down arrow) Interactions are propagated to the controller.
-one-way data binding between local and parent scopes
Controller:
1$scope.setselected = function (NewValue) {...};
Html:
Smartyinput instruction Character:
1scope: {select: "&", ...} ... scope.select ({"X": parseint (Scope.index) + 1});
The smartyinput directive binds the setselected () function in the controller scope to the Select () function in the directive scope so that the specifier uses it without changing the setselected () function.
@: Bind evaluation expressions to local scope
Controller:
1$scope.prefix = ""
Html:
Smartysuggestions instruction Character:
1scope: {prefix: "@", ...}
Using the smartysuggestions directive, you can display the prefix value in the suggestion menu, so you use the evaluate expression {{prefix}}. This binding method is more common in many complex expressions, such as: Next-index= "{{selected + 1}}".
Promises
Promise is the technique used to perform asynchronous tasks. A promise has a method named then () that executes as a parameter to the callback function that is executed when the promise is executed. When the asynchronous task completes, promise passes a message to the callback function. When a change is detected in the prefix prefix entered by the user, promise appears in Smarty code, and then we use $http to execute a GET request to update the list that is displayed to the user's suggestion.
This process seems to be like this:
When $scope. $watch registers a change in the value of $scope.prefix (note that this is bound to the user UI input interface), the Getsmartysuggesction () is invoked.
2var promise = Smartysuggestor.getsmartysuggestions ($scope. Prefix);p romise.then (function (data) {
$scope. Suggestions = data;});
In Getsmartysuggesctions (), $http. Get returns a promise that participates in the server response.
13function getsmartysuggestions (prefix) {
requestparams["Query"] = Escape (Prefix.tolowercase ());
var promise = $http. Get (Requesturl (),
{
Params:requestparams,
Cache:true
}
). Then (function (response) {
Return Response.data.slice (0, 5). Map (function (item) {
return item. Name;
});
});
return promise;}
The server response looks like this:
[{"id": "Name": "Portrait Photography"},{"id": "Name": "Commercial photography"},{"id": "Name": "Pet Photography "},{" ID: "Name": "Event Photography"},{"id": "," name ":" Headshot Photography "}]
Next, we call the then () method that exists in promise, which is passed in the parse server response callback. The then () method returns a new promise that handles the parsed response and is stored in the promise returned through Getsmartysuggestions ().
The parsed response looks like this: ["Portrait Photography", "Commercial photography", "Pet Photography", "Event photography", "headshot Photography "].
Finally, back to $scope $watch, we call the then () method in promise to assign these parsed responses to the variable suggestions.
4var promise = Smartysuggestor.getsmartysuggestions ($scope. prefix);
Promise.then (function (data) {
$scope. suggestions = data;
});