I'm pretty new to JavaScript & Angular and I'm trying to test this controller but I'm missing something here. Here's the error:
PhantomJS 1.9.7 (Mac OS X) Controller: UserCalendarCtrl Calendar resize based on width resize should call mobile FAILED
spyOn could not find an object to spy upon for width()
user-calendar-controller.spec.js
'use strict';
describe('Controller: UserCalendarCtrl', function() {
var controller,
mockScope,
VivaCalendar;
beforeEach(module('vivaAngularApp', 'ui.calendar'));
beforeEach(inject(function($controller, $rootScope, _VivaCalendar_) {
mockScope = $rootScope.$new();
controller = $controller('UserCalendarCtrl', {
$scope: mockScope
});
VivaCalendar = _VivaCalendar_;
}));
describe('Calendar resize based on width', function() {
it('should set a width', function() {
expect(mockScope.width).toBeDefined(true);
});
describe('resize', function() {
beforeEach(function (mockScope){
spyOn(mockScope, 'width').and.callFake(function(){
return 700;
});
});
it('should call mobile', function() {
expect(mockScope.uiConfig).toEqual(VivaCalendar.uiConfig('mobile'));
});
});
});
describe('event sources', function(){
it('should return event sources', function() {
expect(mockScope.eventSources).toEqual([mockScope.eventSource]);
});
it('should take event source', function(){
expect(mockScope.eventSource.url).toEqual('http://162.243.222.54/fullcalendar/new_fechas_insp.php');
});
});
});
user-calendar-controller.js
'use strict';
app.controller('UserCalendarCtrl', ['$scope', '$window', '$location', 'VivaCalendar', function($scope, $window, VivaCalendar, $location) {
$scope.width = $window.innerWidth;
$scope.$watch('width', function(width) {
if (width < 768) {
$scope.uiConfig = VivaCalendar.uiConfig('mobile');
} else {
$scope.uiConfig = VivaCalendar.uiConfig();
}
});
$scope.eventSource = {
url: 'http://162.243.222.54/fullcalendar/new_fechas_insp.php'
};
$scope.eventSources = [$scope.eventSource];
}]);
viva-calendar.js
'use strict';
app.service('VivaCalendar', function() {
var UiConfig = function(size) {
this.calendar = {
defaultView: 'month',
allDaySlot: false,
minTime: 8,
maxTime: 22,
timeFormat: {
agenda: 'h:mm{ - h:mm}TT'
},
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek'
},
buttonText: {
prev: '‹', // <
next: '›', // >
prevYear: '«', // <<
nextYear: '»', // >>
today: 'Ver el día de hoy',
month: 'mes',
week: 'semana',
day: 'día'
},
columnFormat: {
month: 'ddd', // Mon
week: 'ddd d/M', // 9/7 Mon
day: 'dddd M/d' // 9/7 Monday
},
monthNamesShort: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
dayNamesShort: ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab'],
dayNames: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],
editable: false,
hiddenDays: [0, 6]
};
if (size === 'mobile') {
this.calendar.defaultView = 'agendaDay';
this.calendar.header.right = 'month, agendaDay';
}
};
this.uiConfig = function(size) {
return new UiConfig(size);
};
});
The goal of a spy is to replace a function by another one that records the function calls, and potentially does something other than the replaced function.
width here is not a function. It's a simple attribute of type number. So it makes no sense to spy on it. If you want the width of the scope to be 700, you simply need
mockScope.width = 700;
Related
I am using the following code to add markers in leaflet:
.controller('MapController',
[ '$scope',
'$cordovaGeolocation',
'$stateParams',
'$ionicModal',
'$ionicPopup',
'$http',
function(
$scope,
$cordovaGeolocation,
$stateParams,
$ionicModal,
$ionicPopup,
$http
) {
$scope.$on("$stateChangeSuccess", function() {
$scope.map = {
defaults: {
tileLayer: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
maxZoom: 18,
zoomControlPosition: 'bottomleft'
},
markers : {},
events: {
map: {
enable: ['context'],
logic: 'emit'
}
}
};
$scope.locate();
});
$scope.locate = function(){
$scope.map.center = {
lat : location.lat,
lng : location.lng,
zoom : 12,
};
var Location = function() {
if ( !(this instanceof Location) ) return new Location();
this.lat = "";
this.lng = "";
this.name = "";
};
$ionicModal.fromTemplateUrl('templates/addLocation.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.map.markers.push=({
lat:35.654,
lng:73.244,
message:'demo 1'
})
$scope.map.markers.push=({
lat:38.654,
lng:73.244,
message:'demo 2'
})
$scope.$on('leafletDirectiveMap.click', function(event, locationEvent){
$scope.newLocation = new Location();
$scope.newLocation.lat = locationEvent.leafletEvent.latlng.lat;
$scope.newLocation.lng = locationEvent.leafletEvent.latlng.lng;
$scope.modal.show();
});
$scope.saveLocation = function(lat, lang) {
//LocationsService.savedLocations.push($scope.newLocation);
//alert(lat + " - " + lang);
var link = 'http://192.168.5.110/server/addLocation.php';
var json1 = {l1 : lat, l2 : lang , l3: sessionStorage.getItem('loggedin_phone')};
$http.post(link, { data: json1 })
.then(function (res){
$scope.response = res.data.result;
if($scope.response.created=="1"){
$scope.title="Thank You";
$scope.template="Mobile Toilet Added!";
//no back option
/*
$ionicHistory.nextViewOptions({
disableAnimate: true,
disableBack: true
});
$state.go('login', {}, {location: "replace", reload: true});
*/
}else if($scope.response.exists=="1"){
$scope.title="Duplication";
$scope.template="This Location is already added!";
}else{
$scope.title="Failed";
$scope.template="Contact Our Technical Team";
}
var alertPopup = $ionicPopup.alert({
title: $scope.title,
template: $scope.template
});
});
$scope.modal.hide();
};
$cordovaGeolocation
.getCurrentPosition()
.then(function (position) {
$scope.map.center.lat = position.coords.latitude;
$scope.map.center.lng = position.coords.longitude;
$scope.map.center.zoom = 18;
$scope.map.markers.now = {
lat:position.coords.latitude,
lng:position.coords.longitude,
focus: true,
draggable: false,
//message: ''
};
}, function(err) {
// error
console.log("Location error!");
console.log(err);
});
};
}]);
But only the demo2 marker is displaying.
Is there a way to show multiple markers on the leaflet map by using JSON data of latitudes and longitudes loaded from API?
<leaflet defaults="defaults" event-broadcast="events" lf-center="center" markers="markers" layers="layers" id="global-map" width="100%" height="240px"></leaflet>
<leaflet defaults="defaults2" event-broadcast="events2" lf-center="center2" markers="markers2" layers="layers2" id="global-map2" width="100%" height="240px"></leaflet>
I am trying to use ngMaterial in my Angular app and getting the errors: ReferenceError: $event is not defined and TypeError: Cannot read property 'confirm' of undefined. I have looked at the ngMaterial docs and am using the code from this example: https://material.angularjs.org/latest/demo/dialog but can't find what I am doing wrong.
The ReferenceError refers to this line:
$timeout($scope.showConfirm($event), 500);
And the TypeError refers to:
var confirm = $mdDialog.confirm()
Below is my code:
html:
<div style="height: 100%">
<h1>TEST</h1> <!--NOT SHOWING ON PAGE WHICH MEANS THIS IS NOT BEING INVOKED WHEN
URL IS: '/getLocation' like it should-->
<ui-gmap-google-map
class="md-primary md-raised" ng-click="showConfirm($event)"
center='map.center'
zoom='map.zoom'
draggable='map.draggable'
dragging='map.dragging'
refresh='map.refresh'
options='map.options'
events='map.events'
pan='map.pan'>
<ui-gmap-marker
idKey='1'
events='map.events'
coords='map.center'
>
</ui-gmap-marker>
</ui-gmap-google-map>
<script src='//maps.googleapis.com/maps/api/js?key=AIzaSyD4_0KuPivZyV-1EwNGmBCgLc_Z0o8Dyw8'></script>
</div>
Controller:
(function (window, ng) {
ng.module('app', ['uiGmapgoogle-maps', 'ui.router', 'ngMaterial'])
.config(function ($stateProvider) { //had: , $stateChangeError included in the function parameters, but that caused error
$stateProvider.state('getLocation', {
url: '/getLocation',
templateUrl: 'getlocation.html',
controller: 'GetlocationCtrl',
});
})
.controller('GetlocationCtrl', ['$scope', "uiGmapLogger", "uiGmapGoogleMapApi", "$state", "$stateParams", "$timeout",
function ($scope, $log, GoogleMapApi, $state, $stateParams, $timeout, $mdDialog) {
$log.currentLevel = $log.LEVELS.debug;
center = { latitude: 49.22, longitude: -122.66 }; //default center
console.log($stateParams);
$scope.map = {
center: center,
pan: false,
zoom: 16,
refresh: false,
events:
{ click: function newCenter(mapModel, eventName, originalEventArgs)
{
$scope.$apply(function(){
var e = originalEventArgs[0];
$scope.map.center = { latitude: e.latLng.lat(), longitude: e.latLng.lng() };
$timeout($scope.showConfirm($event), 500);
});
}
}
}
$scope.map.circle = {
id: 1,
center: center,
radius: 500, //(current time - date lost)*km/hour
stroke: {
color: '#08B21F',
weight: 2,
opacity: 1
},
fill: {
color: '#08B21F',
opacity: 0.5
},
geodesic: false, // optional: defaults to false
draggable: false, // optional: defaults to false
clickable: true, // optional: defaults to true
editable: false, // optional: defaults to false
visible: true, // optional: defaults to true
events: {
dblclick: function () {
$log.debug("circle dblclick");
},
radius_changed: function (gObject) {
var radius = gObject.getRadius();
$log.debug("circle radius radius_changed " + radius);
}
}
};
$scope.showConfirm = function (ev) {
// Appending dialog to document.body to cover sidenav in docs app
var confirm = $mdDialog.confirm()
.title('Would you like to delete your debt?')
.textContent('All of the banks have agreed to forgive you your debts.')
.ariaLabel('Lucky day')
.targetEvent(ev)
.ok('Please do it!')
.cancel('Sounds like a scam');
$mdDialog.show(confirm).then(function() {
$scope.status = 'You decided to get rid of your debt.';
}, function() {
$scope.status = 'You decided to keep your debt.';
});
};
} ]); //end of controller
//THIS LISTENER DOES NOT DO ANYTHING
// $scope.map.event.addListener(map, 'click', function(event) {
// alert(event.latLng); // in event.latLng you have the coordinates of click
//});
//function confirmLocation() {
// alert('Use this location as {{petName}}\'s last location?')
//}
})(window, angular);
Your controller does not have mdDialog injected, and there is a issue in the way you are injecting, change like below,
controller('GetlocationCtrl', ['$scope', "uiGmapLogger", "uiGmapGoogleMapApi", "$state", "$stateParams", "$timeout","$mdDialog",
function ($scope,uiGmapLogger, uiGmapGoogleMapApi, $state, $stateParams, $timeout, $mdDialog) {
I have a property in my factory and a sync() method to update it, but when accessing from controller the value never changes.
My router: (Initialise events with resolve)
'use strict';
myApp
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('app', {
abstract: true,
views: {
'header': {
controller: 'HeaderCtrl',
templateUrl: 'views/header/_header.html'
},
'footer': {
templateUrl: 'views/footer/_footer.html'
}
}
})
.state('app.events', {
url: '^/',
views: {
'content#': {
controller: 'EventsCtrl',
templateUrl: 'views/events/_events.html',
resolve: {
postPromise: ['EventsServ', function(EventsServ) {
return EventsServ.getAll();
}]
}
}
}
})
.state('app.about', {
url: '^/sobre',
views: {
'content#': {
templateUrl: 'views/about/_about.html'
}
}
})
.state('app.contact', {
url: '^/contato',
views: {
'content#': {
controller: 'ContactCtrl',
templateUrl: 'views/contact/_contact.html'
}
}
});
}]);
My controller: (Now sync with facebook and update events)
'use strict';
myApp
.controller('EventsCtrl', ['$scope', 'EventsServ', '$filter', '$window', 'Facebook', 'postPromise', '$log', '$timeout', function($scope, EventsServ, $filter, $window, Facebook, postPromise, $log, $timeout) {
$scope.alerts = [];
$scope.events = EventsServ.all(); // <<<< Never update, keep the same value obtained in router.
$scope.periods = [{
label: 'HOJE',
labelColor: 'success',
startTime: $filter('clearTime')(new Date()),
endTime: $filter('clearTime')(new Date()),
events: []
}, {
label: 'PRÓXIMOS DIAS',
labelColor: 'primary',
startTime: $filter('clearTime')($filter('addDay')(new Date(), 1)),
endTime: $filter('clearTime')($filter('addDay')(new Date(), 8)),
events: []
}, {
label: 'PRÓXIMAS SEMANAS',
labelColor: 'warning',
startTime: $filter('clearTime')($filter('addDay')(new Date(), 9)),
events: []
}];
if (postPromise.status >= 200 && postPromise.status < 300) {
angular.forEach($scope.events, (function(event) {
var eventDate = $filter('clearTime')(event.start_time);
angular.forEach($scope.periods, (function(period) {
if (eventDate >= period.startTime && (eventDate <= period.endTime || !period.endTime)) {
period.events.push(event);
}
}));
}));
Facebook.getLoginStatus(function(response) {
if(response.status === 'connected') {
EventsServ.sync();
$log.info($scope.events);
} else {
$log.info('notLoggedIn');
}
});
} else {
$scope.alerts.push({
type: 'danger',
msg: 'Ooops! Não foi possível buscar os eventos.'
});
}
$scope.openEvent = function(event) {
$window.open('http://facebook.com/events/' + event.id, '_blank');
};
$scope.closeAlert = function(index) {
$scope.alerts.splice(index, 1);
};
}])
.filter('addDay', function() {
return function(date, days) {
return new Date(date.setDate(date.getDate() + days));
};
})
.filter('clearTime', function() {
return function(date) {
var d = new Date(date);
d.setHours(0,0,0,0);
return d;
};
});
I build my view looping through $scope.events.
My factory:
'use strict';
myApp
.factory('EventsServ', ['$http', '$q', 'Facebook', 'PagesServ', '$log', function($http, $q, Facebook, PagesServ, $log) {
var factory = {
events: []
};
factory.all = function() {
return factory.events;
};
factory.getAll = function() {
return $http.get('/events.json')
.success(function(response) {
angular.copy(response, factory.events);
})
.error(function(response) {
$log.error('Failed to get events.');
});
};
factory.sync = function() {
PagesServ.getAll().then(function(response) {
var pages = PagesServ.pages;
var events = [];
var pagesPromises = [];
var eventsPromises = [];
angular.forEach(pages, function(page, key) {
pagesPromises.push(Facebook.api(page.facebook_id, function(response) {
page.facebook_id = response.id;
page.name = response.name;
page.image = 'image.jpg';
delete page.events;
delete page.created_at;
delete page.updated_at;
}));
eventsPromises.push(Facebook.api(page.facebook_id + '/events', function(response) {
var pageEvents = response.data;
angular.forEach(pageEvents, function(event, key) {
event.page = page;
});
events = events.concat(pageEvents);
}));
});
$q.all(pagesPromises).then(function() {
$log.info(pages);
}, function(reason) {
$log.error('Failed to syncs pages: ' + reason);
});
$q.all(eventsPromises).then(function() {
factory.events = [];
angular.forEach(events, function(event, key) {
var eventSynced = {
facebook_id: event.id,
image: '',
name: event.name,
description: event.description,
start_time: event.start_time,
end_time: event.end_time,
going: 397,
address: '...',
page: event.page
}
factory.events.push(eventSynced);
});
$log.info(factory.events); // <<<<< Here the new value is correct!
}, function(reason) {
$log.error('Failed to syncs events: ' + reason);
});
});
};
return factory;
}]);
The new value of the property inside factory is correct when printing to console, but in controller the value never changes, is always [ ].
When have data I want to stay in sync between a controller and a factory, or a factory and multiple controllers, I set the data item I want to access in my controller to the object or array in the factory:
// in your controller change this
$scope.events = EventsServ.all();
// to use the object
$scope.events = EventsServ.events;
In your sync function where you are iterating over the events, push each one into a temporary array, then use angular.copy to make the update to the array available to the controller.
// at the line right before you log the events in the factory use
angular.copy(tempArray, factory.events);
$log.info(factory.events);
More info: http://www.justinobney.com/keeping-angular-service-list-data-in-sync-among-multiple-controllers/
I am using John Papa's Angular HotTowel and I don't know how to incorporate Angulars ng-grid into the html. Here is what I've added thanks to wonderful help from stondo. Breeze seems to be adding extra information that is no allowing ng-grid to render the data in the grid. Is there a way to strip the extra info that breeze sends or a work around for ng-grid to behave correctly with breeze data?
angular.module('app').controller(controllerId,
['common', 'datacontext','$scope', '$http', grid2]);
function grid2(common, datacontext, $scope, $http) {
.....
.....
} else {
$http.get('/breeze/Breeze/NoBadgePersonnels').success(function (largeLoad) {
$scope.setPagingData(largeLoad, page, pageSize);
});
activate();
function activate() {
common.activateController([mockData()], controllerId)
.then(function() { log('Activated Grid View'); });
function mockData() {
return datacontext.getEmployeePartialsNoBadges().then(function (data) {
return vm.grid2 = data.results;
});
}
}
Additional information
Datacontext.js looks as follows:
(function () {
'use strict';
var serviceId = 'datacontext';
angular.module('app').factory(serviceId,
['common', 'config', 'entityManagerFactory', datacontext]);
function datacontext(common, config, emFactory ) {
var EntityQuery = breeze.EntityQuery;
var getLogFn = common.logger.getLogFn;
var log = getLogFn(serviceId);
var logError = getLogFn(serviceId, 'error');
var logSuccess = getLogFn(serviceId, 'success');
var manager = emFactory.newManager();
var $q = common.$q;
var service = {
getPeople: getPeople,
getMessageCount: getMessageCount,
getEmployeePartials: getEmployeePartials,
getEmployeePartialsNoBadges: getEmployeePartialsNoBadges
};
var entityNames = {
personnel: 'Personnel'
};
return service;
function getEmployeePartialsNoBadges() {
var orderBy = 'lname';
var employees; //variable to hold employees once we get them back
//use query using Employees resource
return EntityQuery.from('NoBadgePersonnels')
.select('id, fname, lname, class, zip, cntySnrDte')
.orderBy(orderBy)
.toType('Personnel')
.using(manager).execute()
.then(querySucceeded, _queryFailed)
function querySucceeded(data) {
employees = data.results;
log('Retrieved [Employee Partials] from remote data source', employees.length, true);
//log('Retrieved [Employee Partials] from remote data source');
return employees;
}
}
function _queryFailed(error) {
var msg = config.appErrorPrefix + 'Error retrieving data from entityquery' + error.message;
logError(msg, error);
throw error;
}
=================================
It seems like the grid sees 5 items that I queried for, however the items don't want to display on the cells. Red arrow indicates that it allocated 5 rows, and green arrow indicates that I have selected one of the rows. Still doesn't display the records.
thanks
nick
I had to modify John Papa's Hottowel.Angular template, because it wasn't working as expected with latest angular/breeze versions. I'll later share a github link and a blog post about that.
I was able to get ng-grid working just adding $scope and $http to the controller. Read the comment inside the code block to see how it could be entirely done without inject $http.
(function () {
'use strict';
var controllerId = 'corrieri';
angular.module('app').controller(controllerId, ['common', 'datacontext', '$scope', '$http', corrieri]); //'$http', '$scope',
function corrieri(common, datacontext, $scope, $http) { //,$http, $scope
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
var vm = this;
$scope.corrieriList = [];
vm.corrieri = [];
vm.news = {
title: 'Corrieri',
description: 'Lista Corrieri'
};
vm.title = 'Corrieri';
//ng-grid test
$scope.filterOptions = {
filterText: "",
useExternalFilter: false
};
$scope.totalServerItems = 0;
$scope.pagingOptions = {
pageSizes: [10, 20, 30],
pageSize: 10,
currentPage: 1
};
$scope.setPagingData = function (data, page, pageSize) {
data = data.map(function (item) {
return {
PK_ID: item.PK_ID,
Ragione_Sociale: item.Ragione_Sociale,
Telefono: item.Telefono,
Nazionalita: item.Nazionalita,
Indirizzo: item.Indirizzo,
Cap: item.Cap,
Provincia: item.Provincia,
Descrizione: item.Descrizione
};
});
var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
$scope.corrieriList = pagedData; //.results;
$scope.totalServerItems = data.length;
if (!$scope.$$phase) {
$scope.$apply();
}
};
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
setTimeout(function () {
var data;
if (searchText) {
var ft = searchText.toLowerCase();
$http.get('breeze/Corrieri/GetCorrieri').success(function (largeLoad) {
var myModArray = largeLoad.map(function (item) {
return {
Pk_ID: item.Pk_ID,
Ragione_Sociale: item.Ragione_Sociale,
Telefono: item.Telefono,
Nazionalita: item.Nazionalita,
Indirizzo: item.Indirizzo,
Cap: item.Cap,
Provincia: item.Provincia,
Descrizione: item.Descrizione
};
});
data = myModArray.filter(function (item) {
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
});
$scope.setPagingData(data, page, pageSize);
});
} else {
$http.get('breeze/Corrieri/GetCorrieri').success(function (largeLoad) {
$scope.setPagingData(largeLoad, page, pageSize);
});
}
}, 100);
};
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
$scope.$watch('pagingOptions', function (newVal, oldVal) {
if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}
}, true);
$scope.$watch('filterOptions', function (newVal, oldVal) {
if (newVal !== oldVal) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}
}, true);
$scope.gridOptions = {
data: 'corrieriList',
enablePaging: true,
showFooter: true,
showFilter: true,
enableCellEdit: true,
enableColumnResize: true,
enableColumnReordering: true,
pinSelectionCheckbox: true,
totalServerItems: 'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions
};
//ng-grid test end
activate();
function activate() {
var promises = [getCorrieri()];
common.activateController(promises, controllerId)
.then(function () {
log('Activated Corrieri View');
});
}
//This function was used to get data using Breeze Controller
//and I was even able to use it to bind data to ng-grid
//calling the function getCorrieri inside my controller and binding
//gridOptions data to vm.corrieri or just the name of the function (in my case getCorrieri)
// $scope.gridOptions = { data: getCorrieri}
//Be aware that since we r using a Breeze Controller data retrieved have additional
//informations, so we have to remove those, if we bind using vm.corrieri.
//I found it easier to implement paging using $http and $scope, even though I think
//I could do it using only $scope and breeze.
//getCorrieri().then(function() {
// angular.forEach(vm.corrieri, function (cor) {
// delete cor._backingStore['$id'];
// delete cor._backingStore['$type'];
// $scope.corrieriList.push(cor._backingStore);
// });
//});
function getCorrieri() {
return datacontext.getCorrieri().then(function (data) {
return vm.corrieri = data.results;
});
}
}
})();
Below you can find my html for reference. Make sure to surround your's ng-grid div with data-ng-controller or just ng-controller='corrieri'
<section id="corrieri-view" class="mainbar" data-ng-controller="corrieri as vm">
<section class="matter">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="widget wgreen">
<div data-cc-widget-header title="Corrieri" allow-collapse="true"></div>
<div class="widget-content text-center text-info">
<div data-ng-controller='corrieri'>
<div class="gridStyle col-md-12" ng-grid="gridOptions">
</div>
</div>
<div class="widget-foot">
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</section>
Btw, don't forget to add 'ngGrid' to your modules list in app.js
var app = angular.module('app', ['ngGrid', other modules])
and also include ng-grid css and js in index.html (that is obvious, but better safe than sorry)
I struggled a few days to get this working properly, so I hope to help anyone out there having the same problem.
Try this out:
angular.module('app').controller(controllerId, ['common', 'datacontext', '$scope', grid]);
function grid(common, datacontext, $scope) {
$scope.gridOptions = {
data: 'vm.employees'
};
activate();
function activate() {
common.activateController([getEmployees()], controllerId)
.then(function () { log('Activated Grid View'); });
}
//get data for employees
function getEmployees() {
return datacontext.getEmployeePartialsNoBadges().then(function (mydata) {
return vm.employees = data;
});
}
}
here is an image of what I see
and here is the code I changed:
function getEmployees() {
return datacontext.getEmployeePartialsNoBadges().then(function (mydata) {
log(JSON.stringify(mydata));
return vm.employees = mydata.data;
});
Here is some additional info showing the data is coming through. Remote data source shows 1496 records. The preview for /breeze/breeze show data. I've blanked out sensitive info.
Here is the getEmployeePartialsNoBadges() method in my datacontext that was using entity framework:
function getEmployeePartialsNoBadges() {
var orderBy = 'lname';
var employees; //variable to hold employees once we get them back
//use query using Employees resource
return EntityQuery.from('NoBadgePersonnels')
.select('id, fname, lname, class, zip, cntySnrDte')
.orderBy(orderBy)
.toType('Personnel')
.using(manager).execute()
.then(querySucceeded, _queryFailed)
function querySucceeded(data) {
employees = data.results; //fillup the variable for employee with results
log('Retrieved [Employee Partials] from remote data source', employees.length, true);
//log('Retrieved [Employee Partials] from remote data source');
return employees;
}
}
============================== Nick ==============================
This is what my new mockup looks like now and I put this in datacontext calling it getPeople:
function getPeople() {
var people = [
{ firstName: 'John', lastName: 'Papa', age: 25, location: 'Florida' },
{ firstName: 'Ward', lastName: 'Bell', age: 31, location: 'California' },
{ firstName: 'Colleen', lastName: 'Jones', age: 21, location: 'New York' },
{ firstName: 'Madelyn', lastName: 'Green', age: 18, location: 'North Dakota' },
{ firstName: 'Ella', lastName: 'Jobs', age: 18, location: 'South Dakota' },
{ firstName: 'Landon', lastName: 'Gates', age: 11, location: 'South Carolina' },
{ firstName: 'Haley', lastName: 'Guthrie', age: 35, location: 'Wyoming' }
];
return $q.when(people);
}
I have reworked html and controller code to clean things up. The html is now call grid2.html and the controller is called grid2.js
(function () {
'use strict';
var controllerId = 'grid2';
angular.module('app').controller(controllerId,
['common', 'datacontext','$scope', grid2]);
function grid2(common, datacontext, $scope) {
var vm = this;
vm.grid2 = [];
$scope.gridOptions = {
data: 'vm.grid2'
};
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
vm.activate = activate;
vm.title = 'Grid2';
activate();
function activate() {
common.activateController([mockData()], controllerId)
.then(function() { log('Activated Grid View'); });
function mockData() {
return datacontext.getPeople().then(function (mydata) {
log(JSON.stringify(mydata));
return vm.grid2 = mydata.data;
});
}
}
}
})();
controller grid2.js
<section class="mainbar" data-ng-controller="grid2 as vm">
<section class="matter">
<div class="container">
<div class="row">
<div class="widget wgreen">
<div data-cc-widget-header title="Grid 2"></div>
<div class="widget-content user">
</div>
this is grid2 test
<div class="gridStyle" ng-grid="gridOptions"></div>
<div class="widget-foot">
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
</section>
Here what the screen looks like now. still no data in the grid:
In the debug, the data property shows undefined still
The mydata does contain array of data
The vm is an empty array on the return statement
The vm.grid becomes empty after the return and I'm unsure what the vm is also
The console show data being present
I had created the directive file like this:
angular.module('myApp')
.directive('rGraph', function() {
return {
link: function ( scope, element, attrs ) {
var width = Math.max($("#graph-container").innerWidth(), 400);
var height = Math.max(width, 550);
var rgraph = new $jit.RGraph({
injectInto: 'graphcontainer',
width: width,
height: height,
background: {
CanvasStyles: {
strokeStyle: '#555'
}
},
Navigation: {
enable: true,
panning: true,
zooming: 10
},
Node: {
color: '#ddeeff',
overridable: true
},
Edge: {
color: '#C17878',
lineWidth: 1.0
},
onCreateLabel: function(domElement, node){
domElement.innerHTML = node.name;
domElement.onclick = function(){
rgraph.onClick(node.id, {
onComplete: function() {
Log.write("done");
}
});
};
},
onPlaceLabel: function(domElement, node){
style = domElement.style;
style.display = '';
style.cursor = 'pointer';
if (node._depth <= 1) {
style.fontSize = "0.8em";
style.color = "#ccc";
} else if(node._depth == 2){
style.fontSize = "0.7em";
style.color = "#494949";
} else {
style.display = 'none';
}
var left = parseInt(style.left);
var w = domElement.offsetWidth;
style.left = (left - w / 2) + 'px';
},
onBeforePlotNode: function(node){
if (node.data.type == 'group') {
node.setData('type', 'square');
} else if (node.data.type == 'judge') {
node.setData('type', 'star');
node.setData('dim', '8');
}
}
});
//Here I need to set the data
rgraph.loadJSON();
rgraph.refresh();
// Completing animations on every change was too much
// TODO come up with better way to watch for changes
rgraph.graph.eachNode(function(n) {
var pos = n.getPos();
pos.setc(-200, -200);
});
rgraph.compute('end');
rgraph.fx.animate({
modes:['polar'],
duration: 2000
});
}
};
});
And my controller is like this:
angular.module('myApp').controller('AnalysisCtrl', ['$scope', '$http', '$q', 'SearchService', function($scope, $http, $q, SearchService) {
$scope.graph_data = {
'id': 'judge_id',
'name': judge.name,
'type': 'judge',
'children': filters
}
My view is where I ma calling directive is like this:
<div id="graphcontainer" r-graph="graph_data"></div>
Now i need to add the data get from controller i.e data of $scope.graph_data into to the rgraph.loadJSON(); of directives.So how to do that.
Thanks
Sabbu