Fix in IE – Angular 1.6.1 Disabling automatic bootstrap. <script> protocol indicates an extension, document.location.href does not match.

When using angular 1.6.1 in IE9, IE10, IE11, I was getting the error:


Disabling automatic bootstrap. <script> protocol indicates an extension,

document.location.href does not match.


This seemed to be an 1.5.x issue, that was fixed in 1.5.11, but I was getting the error in 1.6.1.

To fix the error I switched from automatic bootstrapping (ng-app) to manual bootstrapping.

So I changed: <html xmlns:ng="http://angularjs.org" id="ng-app" ng-app=”myapp">

to: <html>

And after my module declaration:

angular.module('myapp', []);

angular.element(document).ready(function () {
angular.bootstrap(document, ['myapp']);
});

Animate the navigation between pages with CSS3 and Angular 1.x

Just created a code pen to demonstrate the navigation between pages in Angular 1.x by using css3.
The animation should mimic scrolling the pages from top to bottom, now I could have just  used TypeScript,
to calculate the correct scroll position, but in this case I wanted to use pure CSS3.
I had some difficulties to create this animation, because my first reaction was, to try and use ng-if or 
ng-show / ng-hide, to hide the pages that are not visible. After hours of trying, I did not succeed, 
so I tried a different approach, by stacking the pages on top of each other and moving “previous pages” 
outside of the list at the top and moving next pages outside of the list at the bottom, without using 
ng-if or ng-hide.
Note:
- by using a translateX you could make the pages scroll from left to right instead of from bottom to top.
- by switching the values for translateY, you could make the pages scroll from top to bottom.
http://codepen.io/roelvanlisdonk/pen/YGZqgO/"
image

How to pass a function to an attribute directive, without using isolated scope or eval in Angular 1.x

I have created a little POC to demonstrate, how you can pass a function that resides on the scope, to be passed to a attribute directive without using isolated scope or eval in Angular 1.x.

The first button will be focused when the page is loaded.

When you tab on the first button, the default tab action is applied, so the second button is focused.

When you tab on the second button the function, that was passed to the “tab directive” is called. It will set a message on the scope. 

image

 

namespace poc {
'use strict';
const app = angular.module('poc', []);
class PocDirective implements ng.IDirective {
public link: ($scope: IPocScope, $element: ng.IAugmentedJQuery, attrs: ng.IAttributes) => void;
public restrict = 'E';
public template = `

<action-button>

            <button id="button-1" type="button">Tab on this button</button>

        </action-button>

        <action-button>

            <button poc-tab="{ fn: onTab }" type="button">Tab on this button</button>

        </action-button>

        <div ng-bind="message"></div>

`;
constructor(public $timeout:ng.ITimeoutService) {
const self: PocDirective = this;
self.link = self.unboundLink.bind(self);
}
unboundLink($scope: IPocScope, $element: ng.IAugmentedJQuery, attrs: ng.IAttributes) {
const self: PocDirective = this;
function onTab(){
$scope.message = "Tabbed on button";
}
self.$timeout(function() {
const button1 = document.getElementById('button-1');
button1.focus();
});
$scope.onTab = onTab;
}
}
interface IPocScope extends ng.IScope {
message: string;
onTab: () => void;
}
app.directive('poc', ['$timeout', ($timeout) => new PocDirective($timeout)]);
function safeApply($scope: ng.IScope): boolean {
var result = false;
var phase = $scope.$root.$$phase;
if (phase !== '$apply' && phase !== '$digest') {
$scope.$apply();
result = true;
}
return result;
}
/**
* We want to able to use this directive in association with other directives on the same element.
* So we don't use isolated scope, to prevent the error:
*      "Multiple directives [..., ...] asking for new/isolated scope on: ...".
* But we want to be able to pass a function to this directive from outside, 
* that's why we parse the value of the "poc-tab" attribute.
*/
class TabDirective implements ng.IDirective {
public link: (scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ITabAttributes) => void;
public restrict = 'A';
constructor(public $parse: ng.IParseService) {
const self: TabDirective = this;
self.link = self.unboundLink.bind(self);
}
unboundLink(scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ITabAttributes) {
const self: TabDirective = this;
element.bind('keydown keypress', function (event) {
const tabKey = 9;
const tabIsPressed = (event.which === tabKey); 
if (tabIsPressed) {
const optionsAsString: string = attrs.pocTab;
const optionsAsExpression: ng.ICompiledExpression = self.$parse(optionsAsString);
const options: ITabOptions = optionsAsExpression(scope);
options.fn();
safeApply(scope);
event.preventDefault();
}
});
}
}
interface ITabAttributes extends ng.IAttributes {
pocTab: string;
}
export interface ITabOptions {
fn: () => void;
ignore?: boolean; // When true, given fn is NOT executed.
}
app.directive('pocTab', ['$parse', ($parse) => new TabDirective($parse)]);
angular.bootstrap(document, ['poc']);
}

How to fix: ENOENT: no such file or directory, rename … \abbrev (angular cli)

When I was running “npm install -g angular-cli”, I was getting the following error:

npm ERR! npm  v3.10.3                                                 

npm ERR! path C:\Users\Roel\AppData\Roaming\npm\node_modules\.staging\a

bbrev-69492d5e                                                        

npm ERR! code ENOENT                                                  

npm ERR! errno -4058                                                  

npm ERR! syscall rename                                               

npm ERR! enoent ENOENT: no such file or directory, rename ‘C:\Users\Roe

l\AppData\Roaming\npm\node_modules\.staging\abbrev-69492d5e’ -> ‘C:\Use

rs\Roel\AppData\Roaming\npm\node_modules\angular-cli\node_modules\ember

-cli\node_modules\npm\node_modules\abbrev’                            

npm ERR! enoent ENOENT: no such file or directory, rename ‘C:\Users\Roe

l\AppData\Roaming\npm\node_modules\.staging\abbrev-69492d5e’ -> ‘C:\Use

rs\Roel\AppData\Roaming\npm\node_modules\angular-cli\node_modules\ember

-cli\node_modules\npm\node_modules\abbrev’                            

npm ERR! enoent This is most likely not a problem with npm itself     

npm ERR! enoent and is related to npm not being able to find a file.  

npm ERR! enoent

npm ERR! Please include the following file with any support request:  

npm ERR!     C:\dev\angular2\npm-debug.log                            

npm ERR! code 1

My environment consisted of:

  • windows 10 64 bit
  • node v6.4.0
  • npm v3.10.3

This problem was also solved by @davidrensh solution:

npm uninstall -g angular-cli

npm install -g angular-cli

From <https://github.com/angular/angular-cli/issues/1190>

Communicate between controllers in Angular by using a simple pubsub service in TypeScript.

 

I created a really simple angular PubSubService in TypeScript, to allow communication between controllers or directives or services.

 

In the example below, controller 1, fires an event and controller 2 reacts to the firing of the event.

 

 

module dev {
    "use strict";

    var appModule = angular.module("myApp", []);

    appModule.controller("MyController1", ["$scope", "pubSubService", ($scope, pubSubService)

    => new dev.MyController1($scope, pubSubService)]);

    appModule.controller("MyController2", ["$scope", "pubSubService", ($scope, pubSubService)
    => new dev.MyController2($scope, pubSubService)]);

    

 

    export class MyController1 {
        constructor(public $scope: ng.IScope, public pubSubService: PubSubService) {
            // Fire an an event
            pubSubService.publish("my-custom-event", "some publisher data");
            }
    }

    export class MyController2 {
        constructor(public $scope: ng.IScope, public pubSubService: PubSubService) {
            this.handleMyCustomEvent = this.handleMyCustomEvent.bind(this);

            // Subscribe to be notified, when "my-custom-event" is fired.
            pubSubService.subscribe("my-custom-event", this.handleMyCustomEvent);
        }
   
        handleMyCustomEvent(data: any) {
        // Do something, when an event is fired from MyController1.
        }
    }

 

    /**
     * This service can be used to share data between controllers by using a pub sub mechanism.
     */
    export class PubSubService {
        private nextListenerIndex: number;
        private listeners: Array<IListener>;

        constructor() {
            this.listeners = [];
            this.nextListenerIndex = 0; // The first subscription will be located at index 0;

            this.publish = this.publish.bind(this);
            this.subscribe = this.subscribe.bind(this);
            this.unsubscribe = this.unsubscribe.bind(this);
        }

        /**
         * Publish an event.
         * All subscribers will be notified.
         * @param name, is the name of the event and is case insensitive.
         */
        publish(name: string, data?: any) {
            for (var i = 0, length = this.listeners.length; i < length; i++) {
                const listener = this.listeners[i];
                if (listener && listener.name.toLowerCase() === name.toLowerCase()) {
                    listener.handler.call(null, data, listener.subData);
                }
            }
        }

        /**
         * Subscribe to be notified, when an event is published.
         * @param name, is the name of the event and is case insensitive.
         * @returns A token, that can be used to unsubscribe.
         */
        subscribe(name: string, handler: (data?: any, subData?: any) => void, data?: any): number {
            var token = this.nextListenerIndex;
           
            this.listeners[token] = {
                handler: handler,
                name: name,
                subData: data
            };
            this.nextListenerIndex += 1;

            return token;
        }

        /**
         * Remove the event listener subscription.
         * @param token received on subscribing to an event listener.
         */
        unsubscribe(token: number) {

            // This will create holes in the array, but for now we do not care.
            this.listeners[token] = null; 
        }
    }

    export interface IListener {
        // This function will be called when an event is published.
        // Data is the data from the publisher, subData is the data from the subscriber.
        handler: (data?: any, subData?: any) => void;
        name: string;
        subData?: any; // Data from the subscriber.
    }

    angular.service("pubSubService", () => new PubSubService());
}

How to use angular in a fancybox dynamically shown by jquery

In a brownfield application I encountered a old fancybox jquery plugin. This plugin was used throughout the whole application. This fancybox is just a modal dialog.

I wanted the content of the fancybox to be handled by angular.

 

To accomplish this, I used the following code:

 

image

 

 

You can find the code at:

 

https://github.com/roelvanlisdonk/Research/tree/master/Base/Web/src/Web/wwwroot/blog/fancybox

Server side resource rendering with Angular and ASP .NET MVC: pass data from html to controller.

I wanted a ASP .NET MVC view (*.cshtml) to render on the server and pass the static text contained in the the ASP .NET project resource file to an Angular controller, so on the initial page request, all static data is returned to the client. Dynamic data, like grid content would then be requested by a separate JSON call.

The resource data is passed to the Angular controller by using ng-init.

 

For the sake of this blog post I stuffed everything in one *.cshtml page, including CSS en JavaScript.

Of course this would be separate files in an real application.

 

Project resource file

image

 

Layout.cshtml

 

<!DOCTYPE html> <html xmlns:ng="http://angularjs.org" id="ng-app" ng-app="app"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Send initialization data from HTML to Angular controller</title> <style> /* Add some initial styling. */ html, body { background-color: #F1F1F1; font-family: "Open Sans", sans-serif; font-size: 13px; height: 100%; } body { margin: 20px; } [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; } </style> <!-- Library scripts --> <script src="https://code.angularjs.org/1.4.1/angular.min.js"></script> </head> <body ng-cloak> @RenderBody() <div> <div ng-controller="main" ng-init="resources={ textFromResource: '@WebApplication1.Properties.Resources.TextFromResource'}"> <h1>{{ title }}</h1> {{ resources.textFromResource }} </div> </div> <script> // Angular module. (function () { "use strict"; angular .module("app", []); }()); // Angular controller. (function () { "use strict"; function controller($scope) { $scope.title = "Show ASP .NET MVC resoure (*.resx) data to user on initial load."; } angular .module("app") .controller("main", ["$scope", controller]); }()); </script> </body> </html>

 

 

Result

image

How to manually get Angular services in TypeScript

If you manually want to get / use Angular services in TypeScript you can use the following code:

 

/// <reference path="../libraries/angular/angular.d.ts" />
module app {
"use strict";
var appModule = angular.module("app", []);
var injector: angular.auto.IInjectorService = angular.injector(["ng"]);
var httpService: angular.IHttpService = injector.get("$http");
var qService: angular.IQService = injector.get("$q");
}