I'm very new to angular as far as directive
and module
options. I've just made my first module and factory here. The areas in the UL are frequently repeated elsewhere in the app, but are seem like decent candidates for ng-html-unsafe
(plus a function to return the html)
<div>
<label>Machine</label>
<input ng-model="globals.sandbox" placeholder="MachineName"/>
</div>
<label>CodeBase</label>
<input ng-model="codebase" placeholder="Test Release 13.1.0102.00"/>
<label>customer</label>
<input ng-model="customer" placeholder="BankName"/>
<label>case</label> <input type="checkbox" title="standard?" ng-model="isStandard" />
<input ng-model="case" placeholder="76700" />
<div>
<label>relativePathToWebSiteBase</label>
<input ng-model="machineBasePath" placeholder="c$\MFWebContent\Cases\" /> <span class="clickable" ng-click="machineBasePath='c$\\MFWebContent\\Cases\\';">Use MFWebContent</span> <span class="clickable" ng-click="machineBasePath='C$\\Microsoft .Net 3.5 Framework\\products\\Common Framework\\Host\\';">Use local</span>
</div>
<label>dev</label>
<input ng-model="dev" placeholder="dev1" />
<label>Lights on?</label>
<input ng-checked="lights" ng-model="lights" type="checkbox" />
<div data-role="publishing" ng-show="tab == 3">
<div> <h2>visual studio publish dialogs</h2> On first deploy (it should be saved after that)
<ul>
<li ng-class="{true:'value',false:'invalid'}[(globals.sandbox && validcase())==true]">\\<span class="sandbox">{{displaySandbox()}}</span>\{{machineBasePath}}<span class="case">{{displayCase()}}</span>\LoanQuestNETDeploy\</li>
<li> Set it to <span class="value">From a Web site</span></li>
<li ng-class="{true:'value',false:'invalid'}[(globals.sandbox && validcase())==true]">http://<span class="sandbox">{{displaySandbox()}}</span>.company.com/<span class="case">{{displayCase()}}</span>/LoanQuestNETDeploy/</li>
</ul>
</div>
scripting:
<script src="jquery.ba-throttle-debounce.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
function type(obj) {
var obj_type = typeof obj;
return ({
is: function (type) {
return obj_type === type;
},
is_object: function () {
return obj_type === "object";
},
is_func: function () {
return obj_type === "function";
},
is_string: function () {
return obj_type === "string";
}
});
};
function maybe(item,message) {
var _message=message;
return ({
result: function (accessor, __default) {
if (!item) return type(accessor).is_func() ? __default : accessor;
else return type(accessor).is_func() ? accessor(item) : item;
},message:message,
_: function (accessor,message) {
if (!item) return maybe(null,_message);
if (!accessor && type(item).is_func()) {
return maybe(item(),message);
}
if (type(accessor).is_string()) {
if (item.hasOwnProperty(accessor)) return maybe(item[accessor],message);
var result = item[accessor];
if (result) return maybe(item[accessor].call(item),message);
return maybe(result,message);
}
if (type(accessor).is_func()) {
return maybe(accessor(item),message);
}
return maybe(item[accessor],message);
}
});
};
//https://github.com/knockout/knockout/blob/master/src/utils.js
if(!Array.prototype.arrayFirst){
Array.prototype.arrayFirst=function (predicate, predicateOwner) {
var array= this || [];
for (var i = 0, j = array.length; i < j; i++)
if (predicate.call(predicateOwner, array[i]))
return array[i];
return null;
};
}
if(!Array.prototype.arrayMap){
Array.prototype.arrayMap=function (mapping) {
var array = this || [];
var result = [];
for (var i = 0, j = array.length; i < j; i++)
result.push(mapping(array[i]));
return result;
};
}
var app = angular.module('myApp',[])
.factory('globals',function(){
var result={nodeHost:"myMachine.company.com:81",localPath:"C$\\Microsoft .Net 3.5 Framework\\products\\Common Framework\\Host\\",sandbox:"vBcdApp1"};
window.globals=result;
return result;
});
var Service = function(name,path,svc,notes){
var self=this;
this.name=name;
this.path=path;
this.svc=svc;
this.notes=notes;
this.dir="\\"+path.replace("/","\\")+"\\";
this.url="/"+path.replace("\\","/")+"/"+svc;
var getConfig=function(local){
var parsed= local? self.parsedlocal:self.parsed;
return parsed;
};
this.getDefaultDatabase= function(local,returnError){
var parsed=getConfig(local);
var dd=maybe(parsed,"not attempted")
._('configuration',"no configuration")
._('dataConfiguration',"no dataConfiguration")
._(0,"empty dataConfiguration")
._('$',"invalid dataConfiguration")
._('defaultDatabase',"no default database");
var result= dd.result();
if(!result && returnError)
return dd.message;
return result;
};
this.getConnectionString=function(local,propName){
var dd= self.getDefaultDatabase(local);
if(!dd)
return;
var parsed=local? self.parsedlocal:self.parsed;
var connectionStringsJs= parsed.configuration.connectionStrings[0].add;
if(!connectionStringsJs)
return;
var connectionStrings= connectionStringsJs.arrayMap(function(e){return e.$;});
var cs=connectionStrings.arrayFirst(function(e){return e.name && e.name==dd;});
return propName?cs[propName]:cs;
};
var getClients=function(local){
var parsed=getConfig(local);
var eps= maybe(parsed,"not attempted")
._('configuration',"no configuration")
._('system.serviceModel',"no serviceModel")
._(0,"empty serviceModel")
._('client',"no clients")
._(0,"empty clients")
._('endpoint',"no endpoints");
var result=eps.result();
if(!result)
return [eps.message];
var clients = result
.arrayMap(function(a){
return {name:a.$.name,address:a.$.address};
});
return clients;
};
this.localClients=getClients(true);
this.remoteClients=getClients(false);
this.onLocalChanged=function(){
self.localClients=getClients(true);
};
this.onRemoteChanged=function(){
self.remoteClients=getClients(false);
};
};
var PublishCtrl=function($scope,$http,$timeout,globals){
window.publishCtrl=$scope;
$scope.globals=globals;
$scope.sandbox=$scope.globals.sandbox;
$scope.services = [
new Service("Wcf Portal","Services.Host.LoanQuest","WcfPortal.svc"),
new Service("Registration Portal","Services.Host.Registration","WcfPortal.svc"),
new Service("Program Pricing","Services.Host.ProgramPricing","ProgramPricingService.svc"),
new Service("Data Lookup","DataLookupService","DataLookupService.svc","path depth issues"),
new Service("DocumentPrintingService","Services.Host.PrintingService","DocumentPrintingService.svc"),
];
$scope.displayCase= function(){
if($scope.case){
return $scope.case;
}
return "______";
}
$scope.displaySandbox=function(){
if($scope.globals.sandbox){
return $scope.globals.sandbox;
}
return "v___App_";
}
$scope.caseUrl= function(){
return 'http://'+$scope.displaySandbox()+'.company.com/'+$scope.displayCase();
};
$scope.environmentName= function(){
return $scope.customer ? $scope.customer + '-Cust' : 'Standard-';
};
$scope.validcase=function(){
return $scope.case && ($scope.case.length==5 || $scope.isStandard);
}
$scope.deployUrl=function(){
return '/LoanQuestNETDeploy/publish.htm';
};
var ajaxResults={empty:'<span>No data</span>'};
$scope.getSvcJson= function(uri,svc,local){
return $http.get(uri)
.success(function(data,status,headers,config){
console.log('ajax success:'+uri);
window.parsed= data;
if(local){
svc.parsedlocal=data;
svc.onLocalChanged();
} else {
svc.parsed=data;
svc.onRemoteChanged();
}
}).error(function(data,status,headers,config){
console.log('ajax failure');
return {error:status};
});
}
$scope.getUrlStatus= function(subPath,force){ //force is for full custom paths
if(subPath && subPath.length>0 && ($scope.validcase() && $scope.globals.sandbox && !ajaxResults[subPath] && $scope.machineBasePath) || force)
{
ajaxResults[subPath]=ajaxResults.empty;
var targetUrl="http://"+$scope.globals.nodeHost+"/urlstatus?host="+$scope.globals.sandbox+".company.com&path=/"+$scope.case+subPath;
//console.log("getting status of "+targetUrl);
$http.get(targetUrl)
.success(function(data,status,headers,config){
console.log('ajax success:'+JSON.stringify(data)+":"+targetUrl);
ajaxResults[subPath]='<span class="success">'+data+'</span>';
}).error(function(data,status,headers,config){
console.log('ajax failure');
ajaxResults[subPath]='<span class="error" title="'+subPath+'"">error:'+status+' </span>';
});
}
return ajaxResults[subPath];
};
$scope.$watch('[globals.sandbox,case]',Cowboy.throttle( 350, function(){
ajaxResults={empty:'<span class="case">Loading...?</span>'};
}),true);
var setLocal=function(name,defaultVal,isGlobal){
if(!window.localStorage)
return;
var target= isGlobal?$scope.globals:$scope;
var stored=localStorage.getItem(name);
if(!target[name] || stored){
if(stored){
target[name]=stored;
//console.log('found stored:'+name);
} else{
target[name]=defaultVal;
}
}
$scope.$watch((isGlobal?'globals.':'')+name,function(){
$timeout(function(){
if(target[name]){
console.log('storing '+name+' as '+target[name]);
localStorage.setItem(name,target[name]);
} else {
localStorage.removeItem(name);
}},500);
});
};
setLocal('case');
setLocal('sandbox',undefined,true);
setLocal('customer');
setLocal('dev');
setLocal('codebase');
setLocal('isStandard');
setLocal('lights',false);
setLocal('machineBasePath','c$\\MFWebContent\\Cases\\');
};
</script>
This is a small part of a medium-small SPA I'm writing to help me work. I've chopped out a significant chunk of the full html.
Fiddle: http://jsfiddle.net/Maslow/ty2bB/
What would be low hanging fruits for refactoring towards duplication reduction or more reuse?