Dynamically load modules angular - javascript

I'm looking for a way to load a module (js, css and html) with just one directive anytime during the app life.
<my-module id="contacts"></my-module>
And the template of this directive generates
<my-module id="contacts">
<link type="stylesheet" href="modules/contacts/contacts.css">
<script type="text/javascript" src="modules/contacts/contacts.js"></script>
<ng-include src="modules/contacts/contacts.html"></ng-include>
</my-module>
And the .js file creates a new angular module
// modules/contacts/contacts.js
angular.module('my-contacts', [])
.controller(ContactsCtrl, function($scope) { ... });
And the '.html' uses a controller in this module
// modules/contacts/contacts.html
<ul ng-controller="ContactsCtrl">
<li ng-repeat="contact in contacts">{{ contact.name }}</li>
</ul>
It wont work because the page's module <html ng-app="my-app"> does not depends on my-contacts module. So I would like every module to inject itself as a my-app dependency.
I've found every module (object returned by angular.module) contains a requires array with it's dependencies. I've injected my-contacts into that array and this works:
// modules/contacts/contacts.js
angular.module('my-app').requires.push('my-contacts');
angular.module('my-contacts', [])
.controller(ContactsCtrl, function($scope) { ... });
But I can't find this property on the documentation. Is it standard or it can change anytime? anyone knows?
Update
To be clear, this is not to load a single module with a single component, this is meant to load a entire application, imagine it like a launcher (like MacOS dockbar or Ubuntu's unity sidebar) with dynamically added icons and when one of this icons are clicked it should run the module. But I don't know at the webpage start which apps this launcher should be able to launch and I need to add more applications dynamically. As each app can has it's own directives and services I use angular modules as apps.
<body ng-app="my-app">
<ul>
<li ng-repeat="module in modules">
<button ng-click="selectedApp = module.id">{{ module.name }}</button>
</li>
</ul>
<my-module id="{{ selectedApp }}"></my-module>
</body>

I'm not sure you're trying to abstract the code so much.
What you should be able to do:
Make a module
Put a directive in the module with your contacts list
Inject the module into your page. And use the contact list.

Dependencies are usually the second argument of a module definition. i.e:
angular.module('my-app', ['my-contacts']);
Is this what you were referring to? The dependencies and how to inject them correctly?

Related

My page turns blank when I try to use a controller in angular

I have a problem with angular to integrate a controller to my page. The page becomes blank as soon as I try to integrate it.
<div class="container-fluid" ng-app="ods-widgets" ng-controller="myCtrl" >
<ods-dataset-context context="cont" cont-domain="https://data.rennesmetropole.fr" cont-dataset="{{dataset}}">
</ods-dataset-context>
</div>
<script>
var app = angular.module("ods-widgets", []);
app.controller("myCtrl", function($scope) {
$scope.dataset= "statistiques-de-frequentation-du-site-rennes-metropole-en-acces-libre";
});
</script>
Without the controller:
http://jsfiddle.net/5c0xr8f4/13/
With the controller:
http://jsfiddle.net/8796ueyL/
ods-dataset-context is a component (https://github.com/opendatasoft/ods-widgets).
it's a component that I import via CDN.
I just want to control what is inside the cont-dataset
I looked into the library that you mentioned in your comment. It seems that the issue is that ods-widgets is already an angular module that is being imported via the CDN. If you name your own angular module with the same name, you are effectively overwriting this existing module that you have imported. So what you want to do is declare your own angular module and import ods-widgets as a dependency. You can take a look at the Fiddle for a working sample, but the important part is this one:
angular.module("myApp", ['ods-widgets']);
And in your HTML update the ng-app reference:
<div class="container-fluid" ng-app="myApp" ng-controller="myCtrl" >

Adding a new Angular Dependancy

I'm new to angular and I think I'm doing this right but I'm not sure. I just got pushed into a project without much help and I'm trying to figure this out. I need to make some data using a tree view. The old code was using ng-repeat so I need to do something like that. I found a library that can help with that called treeRepeat. I have 0 experience using npm or bower so I just downloaded "module.js" and "tree-repeat.js" and added it to the project and then added it to a bundle and called it in my html page but I get a error injecting module error and I can't figure out why.
I have the error link at bottom but its a huge link and I have no idea on how to hyperlink it.
App.js
var app = angular.module('app', ['angularFileUpload', 'ngSanitize', 'ui.mask', 'ui.select', 'ui.bootstrap', 'ui.bootstrap.tpls', 'angular.filter', 'smart-table', 'colorpicker.module', 'sf.treeRepeat'])
.config(function ($httpProvider) {
//make delete type json to facilitate passing object
//to our generic method.
$httpProvider.defaults.headers["delete"] = {
'Content-Type': 'application/json;charset=utf-8'
};
});
EDIT: New error when I changed the bundle order. It now goes jquery first, treerepeat, and then angularjs.
https://docs.angularjs.org/error/$injector/nomod?p0=sf.treeRepeat
Calling code:
<div class="row">
<ul>
<li sf-treepeat="role in vm.roles">
{{role.RoleName}}
<ul>
<li sf-treecurse></li>
</ul>
</li>
</ul>
Bundle Order (The 2 files I added with tree-repeat are at the end of the angularjs bundle:
#section scripts {
#Scripts.Render("~/bundles/manageUser")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/angularjs")
<script>
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip();
});
</script>
}

Two different layouts in aurelia app

I'd like to use two separate layouts for my aurelia app. Difference between them is that one doesn't have a sidebar. Currently I'm using one layout file defined as below:
<template>
<div class="container">
<router-view></router-view>
</div>
</template>
If an active route needs this sidebar to appear I'm just putting it into its view.
What I'd like to achieve is to add another layout that would have this sidebar by default:
<template>
<require from="../common/elements/sidemenu/sidemenu"></require>
<div class="container">
<sidemenu></sidemenu>
<router-view></router-view>
</div>
</template>
So the question is - how to do this? Is it even possible with an aurelia app to have multiple layouts (or master pages, however you call those)?
Use aurelia.setRoot()
You can manually set up your application by specifying a script with configure instructions in your index.html. Typically, this is set to main.
index.html
<body aurelia-app="main">
In this script you can specify a root view model using aurelia.setRoot('root'). If no argument is provided, the convention is to use 'app'.
main.js
aurelia.start().then(() => aurelia.setRoot());
However, you can inject the aurelia object anywhere in your application, and call the setRoot function at any time to load a different root view model.
home.js
#inject(aurelia)
export class HomeViewModel {
constructor(aurelia) {
this.aurelia = aurelia;
}
doStuff() {
this.aurelia.setRoot('withSidebar');
}
}
One common use case for this is having a login page, and I've created a complete template for this use case that you can review, clone, or fork here: http://davismj.me/portfolio/sentry/

Meteor helpers not available in Angular template

I am learning Meteor and I'm trying to add internationalization support with the tap:18n package. Unfortunately, the template helper function _ is not availble inside Angular modules. For example
<div>{{_ "foo"}}</div>
works, but does not when using it inside a module template :
> index.html
<div ng-app="app" ng-include="'foo.ng.html'">
> foo.ng.html
<div ng-app="bar">
<div>{{_ "bar"}}</div>
</div>
note: app is declared inside foo.js as angular.module('app', ['angular-meteor']);, in the project root level.
Is it possible to make helpers available inside Angular modules?
(note: see referenced issue.)
** Edit **
Same thing happens when trying to render package templates inside another template :
> index.html
<section ng-app="users"
ng-include="'users/usersession.ng.html'">
</section>
> users/usersession.ng.html
<ul class="nav navbar-nav navbar-right">
{{> loginButtons}} <!-- here -->
</ul>
Then I get Syntax Error: Token '>' not a primary expression at column 1 of the expression [> loginButtons] starting at [> loginButtons].
Note: the module users is defined and everything works fine without the {{> loginButtons}} expression.
You can use meteor templates inside angular. Try something like:
<meteor-include src="myTemplate"></meteor-include>
Your template would be something like:
<template name="myTemplate">
<div>{{_ "foo"}}</div>
</template>
Remember when naming .html files, the angular templates will be name.ng.html and the meteor templates will just be name.html

Using routeProvider when not on site root

Sorry if I'm missing something obvious, very new to Angular.
I'm running an application on this page: //hosted.demo.ca/md/SitePages/Home.aspx
I'm trying to set up the routing on the application but the page is just rendering blank with no errors in console.
routeProvider:
var spApp = angular.module('spApp', [])
.config(function($routeProvider){
$routeProvider.when('/userView',
{
templateUrl: 'partials/userView.html',
controller: 'userCtrl'
})
});
and my html like such:
<div id="mdContainer" ng-cloak>
<!-- Navigation -->
<div id='mdSidebar'>
<ul>
<li id="menuHome"><a href='#'><span>Home</span></a></li>
<li id="menuUsers"><a href='#/userView'><span>Users</span></a></li>
<li id="menuGroups"><a href='#'><span>Groups</span></a></li>
<li id="menuSites"><a href='#'><span>Sites</span></a></li>
<li id="menuReports"><a href='#'><span>Reports</span></a></li>
</ul>
</div>
<!-- Main view -->
<ng-view></ng-view>
</div>
Have you added the route module? Please try using something like:
var spApp = angular.module('spApp', ['ngRoute'])
See here for more information about this. In newer versions of Angular the route functions were moved to a separate module.
Also I can tell you from personal experience that it is very easy to forget to add the angular-route.js file into your html file using something like:
<script src="path/to/angular-route.js">
If you use bower you can easily set this up with:
bower install angular-route

Categories

Resources