AngularJS, ocLazyLoad & loading dynamic States - angularjs

app
define(['angular', 'angular-ui-router', 'ocLazyLoad', 'config/common',
'layout/services/menuService'],
function(angular) {
'use strict';
var $stateProviderRef = null;
var $urlRouterProviderRef = null;
return angular.module('app', ['ui.router', 'oc.lazyLoad', 'app.common', 'app.layout']);
});
app.config
define(['app'],function(app){
app.config(function($locationProvider, $stateProvider, $urlRouterProvider, $ocLazyLoadProvider) {
$urlRouterProviderRef = $urlRouterProvider;
$stateProviderRef = $stateProvider;
$urlRouterProviderRef.otherwise('/');
$locationProvider.html5Mode({enable: true, requireBase: false}); //.hashPrefix('!');
$ocLazyLoadProvider.config({
events: true,
debug: false
}); }); });
app.run
define(['app'],function(app) {
app.run(function ($q, $rootScope, $state, $window, menuSvc) {
menuSvc.all().success(function(viewStates) {
var startUp = undefined;
angular.forEach(viewStates, function(viewState, key){
var viewStateUrl = undefined;
if (viewState.isStartUp == true && startUp == undefined) {
startUp = viewState.name;
}
var state = {
"url": viewState.url,
"name": viewState.name,
"views": []
}
angular.forEach(viewState.views, (function(view) {
var myView = {
"controller" : view.controller,
"templateUrl" : view.templateUrl,
"resolve" : { }
};
myView.resolve.loadController = function($ocLazyLoad)
{
return $ocLazyLoad.load(
{
"name": view.moduleName,
"files": view.controllerFiles
})
};
state.views[view.viewName] = myView ;
}));
$stateProviderRef.state(viewState.name, state);
})
$state.go(startUp);
})
}); });
Solved:
The error was in a combination of areas. The complete solution is below. I am not happy about the solution to this outcome as mentioned below and welcome ideas. Basically I would have preferred a more agnostic binding of the resolve method to my states in the app.run file.

I have this working, although I am not quite happy with the code and I will explain at the end. First off, I found a path to my solution from this Stackoverflow Prior Question
1. app.js
The only change I made from above was to add the ShellCtrl location:
define(
[
'angular', 'angular-ui-router', 'ocLazyLoad', 'config/common',
'layout/services/menuService', 'layout/controllers/ShellCtrl'],
.....
2. app.config:
Nothing changed from above.
3. app.run
define(['app'],function(app) {
app.run(function ($q, $rootScope, $state, $window, menuSvc) {
menuSvc.all().success(function(states) {
angular.forEach(states, function (state) {>
try{
/// for the Header
state.views.header.resolve[state.views.header.data.controllerAlias] =
function($ocLazyLoad){
return $ocLazyLoad.load({
"name": state.views.header.data.controllerAlias,
"files": state.views.header.data.controllerFiles})};
/// for the Footer
state.views.footer.resolve[state.views.footer.data.controllerAlias] =
function($ocLazyLoad){
return $ocLazyLoad.load({
"name": state.views.footer.data.controllerAlias,
"files": state.views.footer.data.controllerFiles})};
}catch(e){
}
console.log(state);
$stateProviderRef.state(state.name, state);
})
$state.go('app.dashboard');
})
}); });
4. With this as my JSON:
[ { "name": "app", "abstract": true, "url": "", "templateUrl": "app/layout/views/tpl.shell.html", "controller": "ShellCtrl" }, {
"name": "app.dashboard",
"views": {
"header": {
"templateUrl": "app/layout/views/tpl.header.html",
"controller": "HeaderCtrl as header",
"resolve": {},
"data": {
"controllerAlias": "app.layout",
"controllerFiles": [
"app/layout/layout.module.js",
"app/layout/controllers/HeaderCtrl.js"
]
}
},
"footer": {
"templateUrl": "app/layout/views/tpl.footer.html",
"controller": "FooterCtrl as footer",
"resolve": {},
"data": {
"controllerAlias": "app.layout",
"controllerFiles": [
"app/layout/layout.module.js",
"app/layout/controllers/FooterCtrl.js"
]
}
}
} }]
5. Shell.html
<div data-ng-controller="ShellCtrl">{{shell.pageTitle}}
<div data-ui-view="header"></div>
<div data-ui-view="footer"></div>
</div>
6 Sample Controller:
angular.module('app.layout').controller('HeaderCtrl', HeaderCtrl);
/* #ngInject */
function HeaderCtrl($scope) {
var header = this;
header.pageTitle = 'Response coming from HeaderCtrl';
}
7. With this as the output:
What I do not like:
All components of my dashboard are interchangeable. Nothing is static. Depending on the "overall" view, the Header, Footer, SideMenu and Content all change. The link I mentioned above had only 1 interchangeable part, "the Feature" which I assume was main content.
I do not like the fact that I had to hard code each view in the my app.run relative to binding the resolve to each.
If someone knows how I can make this more agnostic, I would greatly appreciate input.

All components of my dashboard are interchangeable. Nothing is static. Depending on the "overall" view, the Header, Footer, SideMenu and Content all change. The link I mentioned above had only 1 interchangeable part, "the Feature" which I assume was main content.
I do not like the fact that I had to hard code each view in the my app.run relative to binding the resolve to each.
If someone knows how I can make this more agnostic, I would greatly appreciate input.
To make this more agnostic, you could implement something more along the lines of this.
Use object properties to iterate each and attempt to load into the respective resolve. Adding more error handling and checks would also help with stability.
3. app.run
define(['app'],function(app) {
app.run(function ($q, $rootScope, $state, $window, menuSvc) {
menuSvc.all().success(function(states) {
angular.forEach(states, function (state) {>
try{
/// try to load for each each view
for (var view in state.views)
{
if (state.views[view]['data']){
state.views[view].resolve[state.views[view].data.controllerAlias] =
function($ocLazyLoad){
return $ocLazyLoad.load({
"name": state.views[view].data.controllerAlias,
"files": state.views[view].data.controllerFiles
}
)};
}
}
}catch(e){
}
console.log(state);
$stateProviderRef.state(state.name, state);
})
$state.go('app.dashboard');
})
}); });

Related

call plugin template /page with script ui.route angularjs?

Hey all can you help me, i want to call css and jquery file for template but one page, i have made it but it does not show its page and plugin file has been called!!
this function app.constant for call a plugin
{
app.constant('MODULE_CONFIG', [
{
name: 'alumnss',
module: true,
files: [
'public/alumni/css/icomoon.css',
'public/alumni/css/simple-line-icons.css',
'public/alumni/css/magnific-popup.css',
'public/alumni/css/owl.carousel.min.css',
'public/alumni/css/owl.theme.default.min.css',
// 'public/alumni/css/salvattore.css',
'public/alumni/css/style.css',
'public/alumni/js/modernizr-2.6.2.min.js',
'public/alumni/js/jquery.easing.1.3.js',
'public/alumni/js/jquery.waypoints.min.js',
'public/alumni/js/jquery.magnific-popup.min.js',
'public/alumni/js/owl.carousel.min.js',
'public/alumni/js/jquery.countTo.js',
'public/alumni/js/main.js'
]
}
]).config(['$ocLazyLoadProvider', 'MODULE_CONFIG', function($ocLazyLoadProvider, MODULE_CONFIG) {
$ocLazyLoadProvider.config({
debug: false,
events: false,
modules: MODULE_CONFIG
});}]);}
2. this route a page
app.config(function($stateProvider, $urlRouterProvider, MODULE_CONFIG) {
$urlRouterProvider.otherwise('/alumnis');
$stateProvider
.state('alumnis', {
url: '/alumnis',
templateUrl: 'alumni.html',
controller:'',
resolve: load(['alumnss']) // **THIS CALL FROM 'MODULE_CONFIG' has been called, But the html page not showing **
})
function load(srcs, callback) {
return {
deps: ['$ocLazyLoad', '$q',
function( $ocLazyLoad, $q ){
var deferred = $q.defer();
var promise = false;
srcs = angular.isArray(srcs) ? srcs : srcs.split(/\s+/);
if(!promise){
promise = deferred.promise;
}
angular.forEach(srcs, function(src) {
promise = promise.then( function(){
angular.forEach(MODULE_CONFIG, function(module) {
if( module.name == src){
if(!module.module){
name = module.files;
}else{
name = module.name;
}
}else{
name = src;
}
});
return $ocLazyLoad.load(name);
} );
});
deferred.resolve();
return callback ? promise.then(function(){ return callback(); }) : promise;
}]
}
}
});
and this image, for page blank not show the template, or something wrong with the code??? help me please???
I have gotten your solution
Change the ocLazyLoad CDN like this
<script data-require="oclazyload#1.0.9" data-semver="1.0.9" src="https://cdnjs.cloudflare.com/ajax/libs/oclazyload/1.1.0/ocLazyLoad.min.js"></script>
and write the code for JQ_CONFIG not MODULE_CONFIG
var app = angular.module('routerApp');
app.constant('JQ_CONFIG', {
callplugincss: [
'style.css'
]
});
app.constant('MODULE_CONFIG', [{
name: 'ngGrid',
module: true,
files: [
'js of ng grid'
]
}]);
and change in dependency
routerApp.config(function ($stateProvider, $urlRouterProvider, MODULE_CONFIG, JQ_CONFIG) {
I think it will work. thanks.

Videogular Angular video player problems with async data and `this.config` in controller

I'm using the Videogular video player for Angular. The HTML code looks like this:
<div ng-controller="ShowController as controller" class="videogular-container">
<videogular vg-theme="controller.config.theme.url">
<vg-media vg-src="controller.config.sources" vg-tracks="controller.config.tracks" vg-native-controls="true"></vg-media>
</videogular>
</div>
In the controller the code looks like this to play my video that is stored in Firebase Storage:
app.controller('ShowController', ['$sce', function($sce) {
this.config = {
preload: "auto",
sources: [
{src: $sce.trustAsResourceUrl("https://firebasestorage.googleapis.com/v0/b/myFirebaseApp.appspot.com/o/videos%2Fen%2Fkingfisher.webm?alt=media&token=b4840120-e531-4699-a757-4e0d999ce9d1"), type: "video/webm"}
],
theme: {
url: "http://www.videogular.com/styles/themes/default/latest/videogular.css"
}
};
}]);
That works great, as long I only want to play one video. But to dynamically select from an array of videos, I wrote this:
app.controller('ShowController', ['$scope', '$firebaseStorage', '$sce', function($scope, $firebaseStorage, $sce) {
var ref = firebase.database().ref();
var obj = $firebaseObject(ref.child($routeParams.id));
obj.$loaded(
function(data) {
console.log("Loaded!")
console.log(data === obj);
$scope.wordObject = data;
console.log($scope.wordObject.videos[0].videoURL);
console.log($scope.wordObject.videos[0].videoMediaFormat);
this.config = {
preload: "auto",
sources: [
{src: $sce.trustAsResourceUrl($scope.wordObject.videos[0].videoURL), type: "video/" + $scope.wordObject.videos[0].videoMediaFormat}
],
theme: {
url: "http://www.videogular.com/styles/themes/default/latest/videogular.css"
}
};
},
function(error) {
console.log("Error: ", error)
});
}]);
The videoURL and videoMediaFormat log just fine. But neither the video source nor the theme loads into the HTML view. The problem appears to be that moving this.config changed the object that this refers to. What is this.config doing?
Can I bind this to the controller using call or apply?
I figured it out:
app.controller('ShowController', ['$scope', '$firebaseObject', '$sce', function($scope, $firebaseObject, $sce) {
// Create Firebase reference
var ref = firebase.database().ref();
var obj = $firebaseObject(ref.child($routeParams.id));
$scope.wordObject = obj;
var controller = this;
obj.$loaded(
function(data) {
console.log(data === obj);
$scope.wordObject = data;
// video player
controller.config = {
preload: "auto",
sources: [
{src: $sce.trustAsResourceUrl($scope.wordObject.videos[0].videoURL), type: "video/" + $scope.wordObject.videos[0].videoMediaFormat},
],
theme: {
url: "http://www.videogular.com/styles/themes/default/latest/videogular.css"
}
};
},
function(error) {
console.log("Error: ", error)
});
}]);

calling a service inside a controller in angularjs

I'm working with ng-resource to do CRUD manipulations as following :
app
.factory('candidatureService',['$resource',
function ($resource) {
return $resource('http://localhost:8080/candidature/candidats', {}, {
update: { method: "PUT"}
});
}]);
I only need PUT in my case.
and in the controller I have this :
app
.controller('CandidatureStartCtrl', function ($scope, candidatureService) {
$scope.candidature = {};
$scope.candidature.guarantor = {};
$scope.submitForm1 = function(isValid) {
console.log('validate form');
// check to make sure the form is completely valid
if (isValid) {
console.log('form 1 is amazing');
console.log($scope.user);
candidatureService.update({},{
"username": "Uchiha",
"nom": $scope.candidature.lastname,
"prenom": $scope.candidature.firstname,
"nomarab": $scope.candidature.arabicLastname,
"prenomarab": $scope.candidature.arabicFirstname,
"genre": $scope.candidature.gender,
"dateNaissance": $scope.candidature.birthdate,
"email": $scope.candidature.email,
"telephone": $scope.candidature.phoneNumber,
"photo": $scope.candidature.photo,
"cin": $scope.candidature.identityDocumentCode,
"adresse": $scope.candidature.address,
"codeMassar": $scope.candidature.codeMassar,
"lieuNaissance": $scope.candidature.placeOfBirth,
"cinPhoto": $scope.candidature.identityDocument,
"anneebac": $scope.candidature.anneebac,
"nomGarant": $scope.candidature.guarantor.fullName,
"lienGarant": $scope.candidature.guarantor.link,
"telephoneGarant": $scope.candidature.guarantor.phoneNumber,
"province": {
"codeProvince" : $scope.candidature.province
}
});
$scope.steps.step2=true;
} else {
console.log('form is invalid');
}
};
});
username is the primary key in my case.
but when I use this controller I'm getting this error message :
TypeError: candidatureService.update is not a function
at new <anonymous> (http://localhost:8080/app/scripts/controllers/candidature-start.js:106:24)
in my index.html I've declared the controller and the service as following :
<script src="scripts/controllers/candidature-start.js"></script>
<script src="scripts/service/candidatureService.js"></script>
and when I access to my page I call the 'CandidatureStartCtrl' which is declared in candidature-start.js :
.state('candidature.start', {
url: '/start',
controller : 'CandidatureStartCtrl',
templateUrl: 'views/tmpl/frontend/candidature-start.html',
containerClass: 'hz-menu',
resolve: {
plugins: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load([
'scripts/vendor/slider/bootstrap-slider.js',
'scripts/vendor/touchspin/jquery.bootstrap-touchspin.js',
'scripts/vendor/touchspin/jquery.bootstrap-touchspin.css',
'scripts/vendor/filestyle/bootstrap-filestyle.min.js'
]);
}]
}
})
So why I'm getting that error message it took me 3 hours but I couldn't figure out whats the problem !
Method names in your services get prepended with a $ when you use $resource, so the call should be to candidatureService.$update

Angular UI Modal, avoid modal scope change reflects in parent scope

I am building an Angular app where I want to control which apps in app list I want to show on home page. There is a section called "Manage Apps" where I can manage visible apps..
http://plnkr.co/edit/RPFvv0ZUB2OSctIQM8pQ?p=preview
The plunkr above explains what I want to achieve..
I have passed list of apps in json from parent scope to modal instance. I want to make changes to one field there which is IsPublished.
Now the problem is, whenever I make changes in isPublished field in Modal, it immediately gets reflected in parent scope. You can see apps being filtered in parent scope behind overlay..
I want to avoid it. I want to reflect the changes to parent scope only when I hit save / ok button.
is there any way to do so?
You need a deep copy of a source use angular.copy.The changes directly reflected to main screen because you bind $scope.apps with $scope.items and hence both are refrencing to the same location.
angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.apps = [
{
"FileSystemObjectType":0,
"Id":1,
"ContentTypeId":"0x01008178C725CC128447AD122168CA03E484",
"Title":"First App",
"AppUrl":{
"__metadata":{
"type":"SP.FieldUrlValue"
},
"Description":"http://www.google.com",
"Url":"http://www.google.com"
},
"AppIcon":{
"__metadata":{
"type":"SP.FieldUrlValue"
},
"Description":"https://unsplash.it/150/?random",
"Url":"https://unsplash.it/150/?random"
},
"CanDelete":false,
"IsPublished":false,
"Priority":null,
"ID":1,
"Modified":"2015-03-04T15:44:36Z",
"Created":"2015-02-26T05:24:00Z",
"AuthorId":9,
"EditorId":9,
"OData__UIVersionString":"1.0",
"Attachments":false,
"GUID":"5a3e620d-461c-4663-8837-36bfd2967dad"
},
{
"FileSystemObjectType":0,
"Id":2,
"ContentTypeId":"0x01008178C725CC128447AD122168CA03E484",
"Title":"App 2",
"AppUrl":{
"__metadata":{
"type":"SP.FieldUrlValue"
},
"Description":"http://microsoft.com",
"Url":"http://microsoft.com"
},
"AppIcon":{
"__metadata":{
"type":"SP.FieldUrlValue"
},
"Description":"https://unsplash.it/150/?random",
"Url":"https://unsplash.it/150/?random"
},
"CanDelete":true,
"IsPublished":false,
"Priority":null,
"ID":2,
"Modified":"2015-03-04T15:44:36Z",
"Created":"2015-02-26T05:25:11Z",
"AuthorId":9,
"EditorId":9,
"OData__UIVersionString":"1.0",
"Attachments":false,
"GUID":"e919eb66-0f2b-4ed4-aad9-3b64400bf09a"
},
{
"FileSystemObjectType":0,
"Id":3,
"ContentTypeId":"0x01008178C725CC128447AD122168CA03E484",
"Title":"App 3",
"AppUrl":{
"__metadata":{
"type":"SP.FieldUrlValue"
},
"Description":"http://google.com",
"Url":"http://google.com"
},
"AppIcon":{
"__metadata":{
"type":"SP.FieldUrlValue"
},
"Description":"https://unsplash.it/150/?random",
"Url":"https://unsplash.it/150/?random"
},
"CanDelete":true,
"IsPublished":true,
"Priority":0,
"ID":3,
"Modified":"2015-03-04T15:44:36Z",
"Created":"2015-02-26T08:06:23Z",
"AuthorId":9,
"EditorId":9,
"OData__UIVersionString":"1.0",
"Attachments":false,
"GUID":"07a63d11-fe94-4fc2-95fc-b7ddf16f160a"
},
{
"FileSystemObjectType":0,
"Id":4,
"ContentTypeId":"0x01008178C725CC128447AD122168CA03E484",
"Title":"Test1",
"AppUrl":{
"__metadata":{
"type":"SP.FieldUrlValue"
},
"Description":"http://www.attini.com",
"Url":"http://www.attini.com"
},
"AppIcon":{
"__metadata":{
"type":"SP.FieldUrlValue"
},
"Description":"https://unsplash.it/150/?random",
"Url":"https://unsplash.it/150/?random"
},
"CanDelete":true,
"IsPublished":true,
"Priority":1,
"ID":4,
"Modified":"2015-03-04T15:44:36Z",
"Created":"2015-02-27T03:58:37Z",
"AuthorId":9,
"EditorId":9,
"OData__UIVersionString":"1.0",
"Attachments":false,
"GUID":"9375eff9-4101-4c1f-ad85-bedc484b355f"
}
];
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.apps;
}
}
});
modalInstance.result.then(function (items) {
$scope.apps = angular.copy(items);
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {
$scope.items = angular.copy(items);
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.items);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
Working Plunker

How can I inject 3rd party javascript files as objects into a factory

I have a 3rdparty.JS file at app\scripts\vendor\3rdparty.JS
angular.module('clientApp').factory('myFactory', function () {
// HOW can I get the 3rdparty.JS file here in form of an object?
// Public API here
return {
};
});
How can I now access the 3rdparty library in form of an object to access its methods?
Me too like using linq in angular apps. Those linq operations are time savers. Fortunately we have a plain javascript library equivalent to this.
linq.js in http://linqjs.codeplex.com/ is awesome and stable.
If someone can port this to bower package in github. That would be much helpful.
However, I tried this below and worked for me,
Full Content in the Plunker - http://plnkr.co/edit/Zy1W3G?p=info
// Add service to your module
//linq.svc.js
(function() {
'use strict';
angular
.module('mymodule')
.factory('$linq', linqService);
function linqService() {
return {
getEnumerable: Enumerable
};
function Enumerable() {
var Enumerable = function(getEnumerator) {
this.GetEnumerator = getEnumerator;
}
...... < Paste the remaining content here >
......
......
// out to global
return Enumerable;
}
}
})();
//Example Usage:
//mycontroller.js
(function() {
'use strict';
angular.module('mymodule')
.controller('mycontroller', MyController);
MyController.$inject = [
'$linq'
];
function MyController(
$linq
) {
var jsonArray = [{
"user": {
"id": 100,
"screen_name": "d_linq"
},
"text": "to objects"
}, {
"user": {
"id": 130,
"screen_name": "c_bill"
},
"text": "g"
}, {
"user": {
"id": 155,
"screen_name": "b_mskk"
},
"text": "kabushiki kaisha"
}, {
"user": {
"id": 301,
"screen_name": "a_xbox"
},
"text": "halo reach"
}]
var queryResult = $linq.getEnumerable().From(jsonArray)
.Where(function(x) {
return x.user.id < 200
})
.OrderBy(function(x) {
return x.user.screen_name
})
.Select(function(x) {
return x.user.screen_name + ':' + x.text
})
.ToArray();
console.log("queryResult==>", queryResult);
}
})();
Example Output:
queryResult==> ["b_mskk:kabushiki kaisha", "c_bill:g", "d_linq:to objects"]

Resources