Silverlight to Angular – 3 (Commands)

In Silverlight, we use Commands to do clean separation of View and ViewModel. If we were not using commanding, we will end up creating code behind code to handle the events fired by the controls and then publish the message from view to viewmodel or call viewmodel method from view. Either way, there is unnecessary code in code behind. With command, we can bind the command to a control event using magic black box (in my case Jounce or your ICommand implementation) which will take care of the wiring control event directly to viewmodel method, leaving our code very clean.

We will reuse the code we did in the last blog since it already has commanding implementation. If you want to know more about how to do commanding, please take a look at the Jounce Command documentation or one of my old blog on commanding.

Problem: Display number of times a button is clicked.

I am not going to explain the Silverlight solution here since it is already explained here. Let’s look at the AngularJS solution here since I conveniently skipped it in the previous blog.

View:

1 <!DOCTYPE html> 2 <html ng-app> 3 <head> 4 <title></title> 5 </head> 6 <body> 7 <div ng-controller="Controller"> 8 Number of Clicks:{{NumberOfClicks}} 9 <button ng-click="onClick()">Click Me</button> 10 </div> 11 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script> 12 <script src="Scripts/Controller.js"></script> 13 </body> 14 </html>

In this example we are interested in line (9). Angular provides a cool directive ‘ng-click’ which will listen to the click event and calls a function in the controller or if it is an expression then it evaluate the expression. It is as simple as that. So in Angular, if you want to use commanding to do clean separation of view and controller, all you have to do is use ng-click directive on a button. From view model perspective, the function view is calling nothing more than just another function and nothing special about it. There are bunch of APIs you can use to create this commanding behavior on different controls and you can find them all here in Angular API directive.

Controller:

1 function Controller($scope) { 2 $scope.NumberOfClicks = 5; 3 $scope.onClick = function() { 4 $scope.NumberOfClicks = $scope.NumberOfClicks + 1; 5 }; 6 }

In Silverlight, not only we can execute the action through command, we have another option enable the command or not. This can be achieved using ng-disabled directive. Will look at how to use that in the following example. One benefit in Angular is that you can pass as many parameters as you want in the function call instead of just one in Silverlight. Let’s take a look at a sample where we can pass multiple parameters in function call.

Following example allow user to enter two numbers and perform an addition and display result. When the user enters non numeric number we want to disable the ‘Sum’ button.

View:

1 <!DOCTYPE html> 2 <html ng-app> 3 <head> 4 <title></title> 5 </head> 6 <body ng-controller="Controller"> 7 First : <input ng-model="numberOne"/><br/> 8 Second: <input ng-model="numberTwo"/><button ng-disabled="IsValid(numberOne, numberTwo)" 9 ng-click="onClick(numberOne, numberTwo)">Sum</button><br/> 10 Sum: {{sum}} 11 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script> 12 <script src="Scripts/Controller.js"></script> 13 </body> 14 </html>

Both first and second number are two-way binding since the user change need to be propagated to model. On button click, we are using ng-click directive to call ‘onClick’ function in the controller and we are passing two parameters numberOne and numberTwo from the UI. If you notice, we also have another directive called ng-disabled, this will make the element disable if it return associated function from control returns false. If the input data collection is a form then you can enable and disable form submit button using Form.$validate.

Controller:

This is nothing but simple java script code which has variable assignments and a function call.

1 function Controller($scope) { 2 $scope.numberOne = 0; 3 $scope.numberTwo = 0; 4 $scope.sum = 0; 5 $scope.onClick = function(first, second) { 6 $scope.sum = Number(first) +Number(second); 7 }; 8 $scope.IsValid = function(first, second) { 9 return !(isNumber(first) && isNumber(second)); 10 }; 11 function isNumber(n) { 12 return !isNaN(parseFloat(n)) && isFinite(n); 13 } 14 }

One another point of interest along the line of ng-click is about other events from other elements. Take a look at this stack overflow question and answer. At the end, there is a comment by Tim Steward which is very interesting. He pointed out that if you do not see any ng- function for the element you are working on, his suggestion is to use Angular-UI

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s