Working on a module based app where depending on the user, I'll load a given template (view) as a module inside a common view. The problem is that the different views require different controllers and they one share a small set of common form inputs.
Based on a call to my server I'll get a JSON response containing what view/controller should be loaded for that user. This solution worked fine earlier as all my controllers were in the global scope:
$scope.corporation.payloadController =
// Contains the String "ComputerPayloadCtrl"
[window]data.corporation.payloadController;
Now however, after I have rewritten the applications to use the angular module design pattern, I get the following error (I no longer use [window]):
Argument 'corporation.payloadController' is not a function, got string
The controller is already defined, so I'm only looking for a way to reference it by String.
.controller('ComputerPayloadCtrl', ['PayloadService', '$scope',
function(PayloadService, $scope) {
$scope.payload = PayloadService.payload;
}])
The more I work with this problem, the more this entire approach I've chosen is bugging me. So if anyone has any suggestions on how to alternatively solve this I'll gladly hear it.
Edit: So I found a very simple workaround, but I'll let the question stand in case there is an actual way to do this.
Related
This reminds me of an old song:
"You see I've been reading samples of an app with no name..."
I'd better stop or I'll hear from Neil Young's lawyers.
I am studying AngularJS on W3Schools and in some of their examples the ng-app attribute is an empty string. In others it has a name for the app. It seems that when there is no name there is also no controller function defined in the client script and the application is automatically wired up from the HTML. But in those examples if I enter a name in the ng-app tag it breaks the page. So that raises two questions:
1 - What's the difference between having an ng-app tag with a name and one with an empty string? Does no name mean no controller function is defined?
2 - Is it bad to have an ng-app with no name? Should I always name my ng-app and load it with a controller function?
"...it felt good to be out from the rain."
Edit: Looking at the alternate question "Using ng-app without a value", it is similar, but it doesn't directly address my question. It asks: How to use ng-app without a value. I'm asking for someone to explain: What is the difference between using ng-app with a value and without a value.
Few points here:
Recommend the official docs because the author is the person knows the framework the best.
There are two ways to bootstrap the angular apps: automatically and manually
when you use with ng-app="appName", angularjs will automatically find the element with the tag 'ng-app' and initialize the application.
when you ignore the ng-app, you need to bootstrap the app yourself:
.
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
recommend always bootstrap app with either manual or auto.
===EDIT===
To be clearer :
The stackoverflow link given by #Animal2 has very good explanation. In a short, before angular version 1.3, you can use ng-app as DOM element attribute without any value, because angularjs will handle everything else for you
:
<div ng-app>
....
</div>
but after version 1.3 it is NOT recommended to use this syntax. Instead you can use the 'auto' way and 'manual' way mentioned earlier.
You can specify an AngularJS module to be used as the root module for the application. This module will be loaded into the $injector when the application is bootstrapped. It should contain the application code needed or have dependencies on other modules that will contain the code. See angular.module for more information.
https://docs.angularjs.org/api/ng/directive/ngApp
Someone has already asked this question
Using ng-app without a value
While it isn't exactly 'incorrect' to have an empty ng-app, it is not recommended and won't work for even a slightly complex app. Think of it as a way to show whip up something quickly.
If there is no ng-app specified, it only means that there is no module to assign controllers (and whatever else you want) to, but as you can see it does still work... for the time being.
After a few days and weeks of programming an application based on MEAN, I got to the problem, that the usualy called server.js-file gets bigger and bigger.
It contains the application setup and configuration, also in there is the Angular-Routing and the Mongod-Queries. So you can imagine...
So my first question is, how to extand the file? For example, what do I need to do, that the Routing is in another file and also the queries are seperate and the application still finds the "way" to it.
Another topic but similar problem: The html-files are big and unclear to read, cause the Navbar (for example) is in each page, but has always the same code. So how would it be possible to inject that specific code into each html-page?
If your HTML file is getting large and difficult to manage and you are using the MEAN stack then you can write a new angular directive to help split up your html into smaller more manageable parts.
Write a new directive in angular for example.
angular.directive('navbar', function(){
return {
restrict: 'E'
templateUrl: 'yourpath/navbar.html
}
Now in your html all you have to insert is the following:
<navbar></navbar>
I'm making a dynamic web page with angular, the content from the main page should change, but to avoid writing too much code i decided to make it generic, but to know what type of content is being requested i need to send this parameter from a link/button with a ng-click, this would'nt be a problem but when i have to change the controllers i can't read the parameter.
ng-click="name='Name change'"
Here i'm trying to change a $rootScope variable named name, i tried
ng-click="$rootScope.name='Name change'"
even with a service function, but looks like doesn't work (i don't know too much about angularjs so i tried )
ng-click="$service.cambiarTipo='Name change'"
i made a plunker http://plnkr.co/edit/1BN76SbUAHuOSHs02gpL?p=preview
If you check the console log, you will see that the variable it's undefined, obviously if i change $rootScope.name from a controller i can see it from the other controller, but that's not useful since i need that feed from the user not the controller.
How i can change a rootScope variable from html?
Here'a one using a shared service between the two controller without using $rootscope at all. http://plnkr.co/edit/maKNHgVH20GxTJeCEveh
Note that ng-click is calling the service function. I'm assuming the function is for changing the name.
ng-click="service.cambiarTipo('Name change')"
You really shouldn't be using $rootScope all that much, let alone modifying it from the template. With that said, you can assign $rootScope to a $scope variable and access from the template like normal scoped variable. plunker
Controller:
$scope.rs = $rootScope
Template:
rs.name = 'Name Change'
I would like to reiterate that this is not something you should be doing as it goes against the angular way.
I have just started working in angular.js and I have created separate angular applications (using ng-app) for separate modules of my application for modularity sake so that change in one module does not bring down the whole application.
Now, i am running into a issue of redirecting from a search form common across all modules to a particular page (in a specific module). I thought of saving the value in $rootScope, but while debugging, I found that $rootScope is per ng-app, so, it will not work.
Am I wrong in designing the application into separate angular applications and should I move everything back into one ng-app? or is my application structure correct and I should look for another way of passing value?
EDIT: - I think I did not provide enough detail earlier.
My application is structured as follows:
module1
- controller\controller-module1.js
- service\service-module1.js
- css\module1.css
- view\ <multiple html files>
module2
- same structure
I was actually using the service-module to make REST calls to the server till now, rather than sharing data.
All the modules are defined with their separate dependencies in app.js:
angular.module('Module1App', ['Module1App.controller','Module1App.service']);
angular.module('Module2App', ['Module2App.controller','Module2App.service']);
controllers and service of each module are defined in their respective controllers-module.js and service-module.js, which reside in different directories as per the structure above.
So, to include the controller and service of a particular module(of, say, module1), I declare the following in a view of that module
<script src="/APP_GUI/modules/common/service/services-common.js"></script>
<script src="/APP_GUI/modules/reports/service/services-module1.js"></script>
<script src="/APP_GUI/modules/common/controller/controllers-common.js"></script>
<script src="/APP_GUI/modules/reports/controller/controllers-module1.js"></script>
So, if I have to move all ng-controllers (defined in separate directories as per the module structure above) into one ng-app (app.js above), I will basically end up including all the controller.js and service.js in all the html views, which will basically mean that if there is an error in any one of the js files, my entire application will be down (i have tried it out).
So, unless I have misunderstood something, I cannot move all ng-controllers under a single app.js.
I am going to try out using shared services to share data.
Please let me know in case anybody has something to say on my conclusion.
I don't think using many ng-app is a good approach. I suggest you using many ng-controller in separate file instead.
You can keep variables inside objects instead of using $scope, which most tutorials you'll find online don't explain.
For example:
/// Define the app
app = angular.module('MyApp',[]);
///Add a cotroller
app.controller('MyFirstController', ['$scope', function($scope){
/// using 'this' you can write local properties
this.firstLocalProperty = 'first Value is acessible only in MyFirstController';
this.secondLocalProperty = 'second Value is acessible only in MyFirstController';
$scope.firstSharedAppProperty = 'This is Shared between all controllers in app';
}]);
app.controller('MySecondController', ['$scope', function($scope){
/// here you can use shared and local properties, you may access shared things in $scope
this.fistProperty = $scope.firstSharedAppProperty;
}]);
You'll see that
> MySecondController.firstProperty
'This is Shared between all controllers in app'
but
> MyFirstController.firstProperty
'first Value is acessible only in MyFirstController'
MyFirstController.firstProperty keeps it's original value because it's not shared.
Basically, you should use different controllers for different templates instead of using different modules. Using controllers, you may share items between them in the $scope variable. Or you can keep variables private using this reference inside objects.
Take a look in this article and you may understand better this way.
You should be using multiple controllers and then using a common service shared between your services. Services in angular are singletons, so they can be shared over and over and over again, and will be common across the board, including between applications if you inject the shared functionality as another application.
var app = angular.module('firstApp');
app.service('myService', function(){
var self = this;
return{
getValue: function(){return self.value},
setValue: function(value){self.value=value}
}
});
app.controller('firstController', ['myService', function(myService){.....}]);
app.controller('secondController', ['myService', function(myService){....});
var secondApp = angular.module('otherApp',['firstApp']);
secondApp.controller('otherController', ['myService', function(myService){.....}]);
more importantly, if its doing anything more than just storing values you can inject functionality for better testing!
i am a beginner when it comes to angular
so here is the fiddle
http://jsfiddle.net/prantikv/knc6vrd9/1/
i have an simple app and as you can see i am just trying out the basics.
The example works fine on jsfiddle but when i run it on my machine i get a huge piece of error staring like this
Error: [ng:areq] Argument 'SimpleCont' is not a function, got undefined
And the ng-repeat doesnt show any output and the text input also doesnt work as well
i have run the page via a local wamp server as well and get the same result
Ommit creating a function, since angularjs is modular and provides you mechanism to create controllers, which can be used in applications.
So in your code, instead of:
function SimpleCont($scope){
$scope.nameList=[
{firstname:'john'},
{firstname:'jane'}
];
}
Create module and controller within it. First use module method from angular, which takes as first parameter name of module ( later to include in ng-app ) and as a second parameter dependency list, which in this situation is empty.
angular.module('myApp', []).
Then invoke controller function on module.
Module method always return itself, so you can add later another contorllers by using dot ..
controller('SimpleCont', function(){
this.nameList=[
{firstname:'john'},
{firstname:'jane'}
];
});
This is code instead of function, this code sets module and assign controller to it.
In your application to use module and created controller within it, set ng-app properly.
instead of:
<div ng-app>
use:
<div ng-app="myApp">
Generally good to know how to create controllers and modules in angularjs for beggining, because later you can learn other curious things like services, factories and also get to know what is $http service and how to use it for making ajax calls.
Also good to automate work thanks to grunt, karma and yeoman.
Here is good tutorial to start.
Here is about yeoman a tool you can use to work with angular.