Created
November 25, 2017 23:04
-
-
Save AndreyChechel/e53db2e0dd40866a17a28f3ad310b20d to your computer and use it in GitHub Desktop.
Retyped.angular in action
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Bridge; | |
using System; | |
using System.Collections.Generic; | |
using Retyped; | |
namespace AngularDemo | |
{ | |
public class App | |
{ | |
[Init] | |
public static void Start() | |
{ | |
// See original sample here: https://docs.angularjs.org/guide/services | |
// Create controller arguments: | |
var myControllerInjectableArgs = new Union<string, angular.angular2.IControllerConstructor.IControllerConstructorFn>[] | |
{ | |
"$scope", | |
"notify", | |
new angular.angular2.IControllerConstructor.IControllerConstructorFn(args => | |
{ | |
// args are supposed to represent "params object[] args", | |
// but it could not be working applied to delegates. | |
// An issue will be created to adapt the syntax to the expected behaviour. | |
// As a workaround, 'Bridge.Arguments' will be used instead: | |
args = Arguments.ToArray(); | |
var scope = args[0]; | |
var notify = (Action<string>) args[1]; | |
scope["callNotify"] = new Action<string>(msg => | |
{ | |
notify(msg); | |
}); | |
return null; | |
}) | |
}; | |
// Construct service arguments: | |
var notifyFactoryArgs = new Union<string, Delegate>[] | |
{ | |
"$window", | |
new Func<dom.Window, Action<string>>(win => | |
{ | |
var msgs = new List<string>(); | |
var handlerFn = new Action<string>(msg => | |
{ | |
msgs.Add(msg); | |
if (msgs.Count == 3) | |
{ | |
win.alert(string.Join("\n", msgs)); | |
msgs.Clear(); | |
} | |
}); | |
return handlerFn; | |
}) | |
}; | |
// Declare module with a controller and a service: | |
var module = angular.angular3.module("myServiceModule", Foo); | |
module | |
.controller("MyController", ToInjectableControllerCtr(myControllerInjectableArgs)) | |
.factory("notify", ToInjectableFn(notifyFactoryArgs)); | |
} | |
[Template("[]")] | |
public static string[] Foo; | |
public static angular.angular2.Injectable<angular.Function> ToInjectableFn(Delegate fn) | |
{ | |
// Any C# delegate is implicitly convertable to "es5.Function". | |
// Based on d.ts file, angular extends "es5.Function" with an additional member, | |
// So it's not actually a new type in TypeScript, but a new type-inheritor in C#. | |
// We can just use any way of casting (direct cast, As<> method, casting method with a proper template attribute): | |
var angularFn = (angular.Function)fn; | |
// Injectable<T> is a type alias for a T or an Array of string/T (T is "Delegate" here). | |
// So we can safely cast "angularFn" to "Injectable<Function>" entity: | |
var injectable = (angular.angular2.Injectable<angular.Function>) angularFn; | |
return injectable; | |
} | |
public static angular.angular2.Injectable<angular.Function> ToInjectableFn(Union<string, Delegate>[] args) | |
{ | |
// That overload allows to create injectables based on arrays of string/functions. | |
// For sake of simplicity and better performance we'll do "unsafe" cast (.As<>), based | |
// on the assumption that "Delegate" is convertable to "angular.Function". | |
// That could be also done using a loop to avoid unsafe cast (that could be tricky though). | |
var strsOrCtrs = args.As<Union<string, angular.Function>[]>(); | |
// Convert C# array into es5.Array: | |
// An issue will be created for that: es5.Array needs to be implicitly convertible to C# array | |
var es5Array = strsOrCtrs.As<es5.Array<Union<string, angular.Function>>>(); | |
// Injectable<T> is a type alias for an Array of string/T (T is "angular.Function" here). | |
// So we can safely cast "es5Array" to "Injectable<angular.Function>" entity: | |
var injectable = (angular.angular2.Injectable<angular.Function>) es5Array; | |
return injectable; | |
} | |
public static angular.angular2.Injectable<angular.angular2.IControllerConstructor> ToInjectableControllerCtr(angular.angular2.IControllerConstructor.IControllerConstructorFn fn) | |
{ | |
// Based on d.ts file, "IControllerConstructor" is a type alias for a union of constructor/self functions. | |
// That means any C# delegate with proper signature (see "IControllerConstructorFn" delegate) | |
// can be implicitly casted to "IControllerConstructor" entity. | |
angular.angular2.IControllerConstructor controllerCtr = fn; | |
// Injectable<T> is a type alias for a T or an Array of string/T (T is "IControllerConstructor" here). | |
// So we can safely cast "controllerCtr" to "Injectable<Function>" entity: | |
var injectable = (angular.angular2.Injectable<angular.angular2.IControllerConstructor>)controllerCtr; | |
return injectable; | |
} | |
public static angular.angular2.Injectable<angular.angular2.IControllerConstructor> ToInjectableControllerCtr(Union<string, angular.angular2.IControllerConstructor.IControllerConstructorFn>[] args) | |
{ | |
// That overload allows to create injectables based on arrays of string/functions. | |
// For sake of simplicity and better performance we'll do "unsafe" cast (.As<>), based | |
// on the assumption that "IControllerConstructorFn" is convertable to "IControllerConstructor". | |
// That could be also done using a loop to avoid unsafe cast (that could be tricky though). | |
var strsOrCtrs = args.As<Union<string, angular.angular2.IControllerConstructor>[]>(); | |
// Convert C# array into es5.Array: | |
// An issue will be created for that: es5.Array needs to be implicitly convertible to C# array | |
var es5Array = strsOrCtrs.As<es5.Array<Union<string, angular.angular2.IControllerConstructor>>>(); | |
// Injectable<T> is a type alias for an Array of string/T (T is "IControllerConstructor" here). | |
// So we can safely cast "es5Array" to "Injectable<IControllerConstructor>" entity: | |
var injectable = (angular.angular2.Injectable<angular.angular2.IControllerConstructor>)es5Array; | |
return injectable; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
// Specific option for accessing Angular through global variables: | |
"loader": { | |
"manualLoading": "true", | |
"skipManualVariables": "true" | |
}, | |
//... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Retyped.angular demo</title> | |
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.js'></script> | |
<script src="js/bridge.js"></script> | |
<script src="js/bridge.console.js"></script> | |
<script src="js/AngularDemo.js"></script> | |
</head> | |
<body ng-app="myServiceModule"> | |
<div id="simple" ng-controller="MyController"> | |
<p>Let's try this simple notify service, injected into the controller...</p> | |
<input ng-init="message='test'" ng-model="message" > | |
<button ng-click="callNotify(message);">NOTIFY</button> | |
<p>(you have to click 3 times to see an alert)</p> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment