Sunday, January 03, 2016

Angular2 and Visual Studio

Introduction

This article explains how to build an Angular2 Beta application using Visual Studio.

Background

Angular Team has released the beta version of Angular2. There are good tutorials on the Angular site. These tutorials are based on npm. However, if you are using Visual Studio as your IDE, you need to make some modifications.

Prerequisites

Download and install npm.
As VS 2015 has integrated npm via Task Runner Explorer, we will use this feature. If you have VS 2013, you need to install Task Runner Explorer.
Get the latest version of TypeScript.

Using the code

1 - Create a new project by selecting TypeScript => HTML Application with TypeScript



2 - You can delete app.css, app.ts and index.html


3 - We need to change the TypeScript compiler options. Since the interface does not cover all options, we need to change these options from the csproj file. Add the following lines after TypeScriptToolsVersion

<TypeScriptModuleKind>System</TypeScriptModuleKind>
<TypeScriptModuleResolution>node</TypeScriptModuleResolution>
<TypeScriptEmitDecoratorMetadata>true</TypeScriptEmitDecoratorMetadata>
<TypeScriptExperimentalDecorators>true</TypeScriptExperimentalDecorators>
<TypeScriptNoImplicitAny>true</TypeScriptNoImplicitAny>

The final should be as below.


4 - Add the package.json to the root of the project.
       {
        "name": "angular2-quickstart",
        "version": "1.0.0",
        "license": "ISC",
        "dependencies": {
            "angular2": "2.0.0-beta.0",
            "systemjs": "0.19.6",
            "es6-promise": "^3.0.2",    
            "es6-shim": "^0.33.3",
            "reflect-metadata": "0.1.2",
            "rxjs": "5.0.0-beta.0",
            "zone.js": "0.5.10"
            }
        }
        
        
After adding package.json, Task Runner Explorer will download the modules under node_modules directory. Wait for the download to finish.

 
5 - Now we are ready to build and Angular2 Beta application. Create a directory called app. Create app.component.ts and boot.ts files under app directory and index.html to root as below.

app.component.ts

        import {Component} from 'angular2/core';
            interface Hero {
            id: number;
            name: string;
        }
        @Component({
            selector: 'my-app',
            template: `
            <h1>{{title}}</h1>
            <h2>{{hero.name}} details!</h2>
            <div><label>id: </label>{{hero.id}}</div>
            <div>
                <label>name: </label>
                <div><input [(ngModel)]="hero.name" placeholder="name"></div>
            </div>
            `
        })
        export class AppComponent {
            public title = 'Tour of Heroes';
            public hero: Hero = {
            id: 1,
            name: 'Windstorm'
            };
        }
        

boot.ts

            import {bootstrap} from 'angular2/platform/browser';
            import {AppComponent} from './app.component';
            bootstrap(AppComponent);
        

index.html

        <html>
        <head>
            <title>Angular 2 QuickStart</title>
            <script src="node_modules/es6-shim/es6-shim.js"></script>
            <!-- 1. Load libraries -->
            <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
            <script src="node_modules/systemjs/dist/system.src.js"></script>
            <script src="node_modules/rxjs/bundles/Rx.js"></script>
            <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
            <!-- 2. Configure SystemJS -->
            <script>
              System.config({
                packages: {
                  app: {
                    format: 'register',
                    defaultExtension: 'js'
                  }
                }
              });
              System.import('app/boot')
                    .then(null, console.error.bind(console));
            </script>
        </head>
        <!-- 3. Display the application -->
        <body>
            <my-app>Loading...</my-app>
        </body>
        </html>
        

6 Now run F5 and see the application running.

Friday, August 30, 2013

Knockout Custom Bindings in Durandal


Instead of using like

$("#mask").inputmask ("d/m/y" , {autoUnmask : true});


it is better to use knockout custom binding.

Define the custom binding in html or make an AMD module.

ko.bindingHandlers.inputmask = {
  init: function (element, valueAccessor, allBindingsAccessor) {
    var obj = valueAccessor(),
              allBindings = allBindingsAccessor(),
              format = allBindings.format;
    $(element).inputmask(format , obj);

    ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
      $(element).inputmask('destroy');
    });
  },
  update: function (element) {
    $(element).trigger('change');
  }
};
or define this in main module.


define(['durandal/system', 'durandal/app', 'durandal/viewLocator' , 'durandal/composition'], function (system, app, viewLocator , composition) {

 composition.addBindingHandler('inputmask', {
        init: function (element, valueAccessor, allBindingsAccessor ) {
              var obj = valueAccessor(),
                  allBindings = allBindingsAccessor(),
                  format = allBindings.format;
              $(element).inputmask(format , obj);


               ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                 $(element).inputmask('destroy');
               });           

        },
        update: function (element) {
            $(element).trigger('change');
        }
    });
......
}
And you can use in view as:
< input data-bind="inputmask :  {autoUnmask: true} , format : 'd/m/y'" id="mask" type="text" / >

Use Non AMD Javascript Libraries in Durandal 2.0


By using shim, jquery libraries can be used in Durandal.

In the main js, configure shim. I have written a module UIInitialize to intialize the interface. This is dependant on jQuery, jQueryGritter and jQueryPulsate.

requirejs.config({
    urlArgs: "bust=" + (new Date()).getTime(),
    paths: {
        'text': '../Scripts/text',
        'durandal': '../Scripts/durandal',
        'plugins': '../Scripts/durandal/plugins',
        'transitions': '../Scripts/durandal/transitions',
        'jQueryGritter': '../Scripts/gritter/js/jquery.gritter',
        'jQueryPulsate': '../Scripts/jquery.pulsate.min',
        'UIInitialize': '../Scripts/UIGeneral',
    },
    shim: {
        'UIInitialize': {
            deps: ['jquery', 'jQueryGritter', 'jQueryPulsate'],
            exports: 'UIInitialize'
        }
    }
});

The UIInitialize.js is as below:

var UIInitialize = function () {
    return {
          init: function () { 
               // Initialize gritter and pulsate
          }
    };
}();


Dynamic router in Durandal 2.0


The router configuratin is in the shell.js file. I need to make this router dynamically managable. To do so, I have used ajax.

The change is in the active method in shell.js file.

activate: function () {
   var routes = [];
 
   $.ajax({
       url: "/Route/Get",
       async: false,
       dataType  : 'json'
       }).done(function (response) {
       routes = response;
   });
 
   router.map(routes).buildNavigationModel();
   return router.activate();
}

The server code is as below.
 public JsonResult Get()
  {
     List route = new List()
     {
        new Route(){ route = "" ,
            title = "Welcome", moduleId = "viewmodels/welcome", nav= true },
        new Route(){ route = "flickr" ,
            moduleId = "viewmodels/flickr" , nav= true }
     };

     return Json(route , JsonRequestBehavior.AllowGet);
}



Managing Css Files in Durandal 2.0


Durandal does not have a mechanism to manage css file for each view. So I have created a plugin to manage css files.

The plugin is as below. I have placed this plugin under durandal/plugins folder

define(['jquery'], function ($) {
    return {
        loadCss : function (fileName) {
            var cssTag = document.createElement("link")
            cssTag.setAttribute("rel", "stylesheet")
            cssTag.setAttribute("type", "text/css")
            cssTag.setAttribute("href", fileName)
            cssTag.setAttribute("class", "__dynamicCss")

            document.getElementsByTagName("head")[0].appendChild(cssTag)
        },
        removeModuleCss: function () {
            $(".__dynamicCss").remove();

        }
    };
});


In the viewmodel, I have used is as below.

define(['plugins/cssLoader'], function (cssLoader) {
    var ctor = function () {
        this.compositionComplete =  function () {
            cssLoader.loadCss("sample.css");
            cssLoader.loadCss("sample2.css");

            // Recommendation : Use Bundle
        };
        this.deactivate =  function () {
            cssLoader.removeModuleCss();
        }
    };

    return ctor;
});

Wednesday, February 15, 2012

The remote server returned an error: (504) Gateway Timeout.

I am using the code below to download file.

WebClient myWebClient = new WebClient();
 myWebClient.DownloadFile(myStringWebResource, fileName);

But suddenly I have started to get 504 error. After adding header, the error has gone.


myWebClient.Headers["User-Agent"] = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0)" +
                " (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";

Thursday, November 10, 2011

Exchange Web Services - OptionalAttendees

When I try to create a new appointment using EWS Managed API, I get the following error.

The request failed schema validation: The element 'OptionalAttendees' in namespace 'http://schemas.microsoft.com/exchange/services/2006/types' has incomplete content. List of possible elements expected: 'Attendee' in namespace 'http://schemas.microsoft.com/exchange/services/2006/types'.

When I add an optional attendee it works but I do not need any optional attendee.

I tried

appointment.OptionalAttendees.Clear();

but no help.

But removing it by using


public readonly static ExtendedPropertyDefinition PidLidOptionalAttendees = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Meeting, 0x00000007, MapiPropertyType.String);


appointment.RemoveExtendedProperty(PidLidOptionalAttendees);

solved my problem.

Saturday, June 18, 2011

Monday, June 13, 2011

Word Automation

I have an application using Ms Word for spell checking. The application impersonates an admin account. The application runs when the specified account is logged on the server. But when the account is not logged on I receive " (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))" error.

I solved the problem as following:

Created a new pool for the application.
Set the identity specified in the web config.
Set load profile true.

Notes:
I could not set the security because the MS Word is not listed in the dcom config. I could add it to there but I did not want to modify the registry.So I had to do as above.

Wednesday, October 13, 2010

Unable to find control id referenced by the 'ControlToCompare' property

When adding a CustomControl dynamically, you receive "Unable to find control id referenced by the 'ControlToCompare' property" error.

I search for the Internet and found no solution. I achieved this bu using JavaScript and jQuery.

In page add a startup script. (I don't like Page.RegisterStartupScript)


$(document).ready(function() {

<%= this.StartUpScript %>

});


In code behind

CompareValidator cv = new CompareValidator();
cv.ID = "customvalidatorid";
cv.ValueToCompare ="Whatever"; // You must set a value. Else, you get an error.


this.StartUpScript += String.Format("document.getElementById(\"{0}\").controltovalidate=\"{1}\";", cv.ClientID, YourControlToCompareId);
this.StartUpScript += String.Format("document.getElementById(\"{0}\").removeAttribute(\"valuetocompare\");", cv.ClientID);

That's it!