Defining functions on scope from a remote controller on the same server - javascript

I am working on a project, which is like a framework which renders data defined in layouts (screens) in format of jsons. For example, i will write ,
{
Name : "First Name",
Row : "1" ,
Type: "Text Box"
}
It will render a Text Box with label "First Name".
I have central service which is the root scope of entire framwork.
My requirement is -
User/Developer will write his own controller and html on the same server outside of the Framework code.
To this controller i will pass my $scope and he will define his new methods and he will also provide a html which i need to render.
This html will use the functions on the scope which can be either from my f/w or his controller.
I have explored -
Angular ajax - http://tutorials.jenkov.com/angularjs/ajax.html
Angoose - https://github.com/tjworks/angoose
I am not sure if my design is correct. Do i need to do it in a completely different way ? OR there is way to achieve what i have designed.
Thanks in advance.

If any one stumbles on this question , this how we solved it
Our application build structure was maven related. So we placed these custom services and html on the same server and wrote a automation program to include these files based on the inputs in properties files.
Once this inclusion was out of the way , angular injector did the rest of adding the service dynamically and html was 'ng-include'-ed.
For those who would like to explore completely angular based solution please check out -
https://github.com/ifyio/angularjs-lazy-loading-with-requirejs

Related

Is it possible to influence a single Angular app from multiple JS scripts?

Quick Summary:
I need to allow two script files to handle different operations for the same angular app. One needs to initialize the app, the other needs to assign a templateCache object to a piece of JSON in localStorage.
Context:
I have several python files which compile/generate html and I have constructed an angular app with this emitted html for my site (which uses CGIs).
The basic construct of the site comes pieces of HTML, which fit together like so:
|------------Header---------------|
|-Navigation-|------Content-------|
|-Navigation-|------Content-------|
|-Navigation-|------Content-------|
|------------Footer---------------|
My Header creates the <head> tag, instantiates my ng-app and uses $templateCache to set up a template that I call from my Navigation code. I had to go with templateCache instead of ngView and ngRoute due to some limitations with how the CGIs emit the html, and the order in which this happens.
My "Navigation" python/html sets up my app with JS like so:
<script>
var responsiveCatalog = angular.module('responsiveCatalog', ['ngStorage']);
....controllers...
....config, etc....
</script>
This Navigation also includes my default templateCache object:
<div ng-include=" 'responsiveItems.html' "></div>
This is all working to show my first templateCache object in the Content section. However, I need to grab many pieces of information from the python generator for the "Content" section (a totally separate file from the "Navigation"), store this data as JSON in localstorage (hence the inclusion of the ngStorage module), and call that as my second templateCache option.
I am not actually sure that I can use two separate instances of Javascript to reference and influence the same Angular app. I know this seems like bad practice, but I am trying to prevent the need to tear down a huge piece of legacy architecture to influence the angular app from two Javascript files in harmony.
Thanks in advance.
You can do
angular.module('myAppName').controllers.... in different files, just make sure the myAppName the same. Bug I don't feel like it work with config, no time to test. If you need any communication between them, check $emit and $broadcast.

Building Real World AngularJS apps, how should I declare my controllers in html. Do I need to declare all in the index.html?

I have an application based on e.g. the Northwind database, in which I have built views for each of the different objects to maintain them CRUD-ly, using AngularJS views and the in typical file structure adopted by most devs.
I have an issue I would like to improve, firstly from all examples I have seen, you need to declare your controller on an index.html file. If one module that a user uses does not require, all the other controllers, is it necessary to load all controllers on the client side. Is there a better way to only declare controllers that are need per view?
Is this the normal behaivor of a Single Page LOB, to preload all necessary dependencies, whether required or not?
No. Don't declare your controllers in your HTML.
The less logic you add in your template, the more flexible your app will be.
The problem with including controllers in your HTML is that if some nested controllers have the same instance var (example foobar), then you don't know which one would be displayed :
<div ng-controller="firstController">
...
<div ng-controller="secondController">
...
{foobar}
Then, the best way is to work with modules and routes. With routes, you can tell AngularJS that your HTML should be controlled by aController.
I you are looking for a good app to start with, take a look at this one.
It has been developped by the AnguarJS team and shows some good practices to follow. You can notice that none of the HTML files contain a reference to a controller.

Accessing Angular app's props and controller functions from external non-Angular plugins

I have an Angular SPA but in it I'm using some non-angular library (Medium Editor [ME from now on] to be exact). I created a directive for ME so if I add a contenteditable element on my views, ME get's instantiated and works properly. So that's not a problem.
The problem is that I also created a special ME extension that requires to make web requests to my server in order to insert correct markup into ME's editable element. But to make these requests it requires some view-model's data and also communicate it back:
it needs to read and set (when undefined) my view model ID
it needs to constantly manipulate some other view model value in order for my SPA to know that it's still processing so other processes get postponed
I thought I'd simply include input type="hidden" ng-model="..." on my page and change its value and trigger input event so Angular would update its model. Hidden input of course doesn't work. So I changed it to input type="text" class="hidden" and keep the functionality.
This does work, but it doesn't seem to be the proper way of doing things as it's hackish. And this mainly works for model value exchange (get/set). How about if I would have to call some controller function? Is that even remotely possible?
I don't want to make ME's extension to rely in any way on Angular library as it has to be purely ME extension and should be reused in non-Angular SPAs (maybe some other lib SPA or just pure simple DHTML web app). But I would like to make it usable in SPAs as well as ME can easily be used to manipulate some element's markup that can be set to view model through a directive.
What it the proper way of communicating with Angular app from external libs that aren't native to Angular?
Additional info
Basically I want to have 4 functions in my custom extension that should somehow access (and manipulate) my Angular view model:
getReferenceId() and setReferenceId(id)
incrementPending() and decrementPending()
Pending counter could be exposed publicly and accessed by my Angular SPA, so it wouldn't process data while extension is still doing its own stuff. But SPA doesn't have any authority over when to set reference ID so it would correctly be read by the extension...
This is usually solved by wrapping external plugins (or their parts) in ng services and directives. You don't need the input tag, just put the data on scope and after changing from non-ng code call $scope.$digest. If you need to watch for data change to trigger something in external library, you can use either ng-change or $scope.$watch.

AngularJS: pass variable from backend while loading a page

This is my first ever trial with Angular JS and am stuck at a very basic step. I have an AngularJS front end and Grails backend. Below are the code snippets I have followed by my question.
URL Mapping entry:
as
"/graph"(controller: 'Graph')
This is my Grails controller/action which renders the GSP:
as
class GraphController {
def index() {
render(view: "../graph", model: [employeeId: "197040"])
}
}
This is the AngularJS file, which is saved as graph.gsp:
When I give the URL: hostname:port/graph I am able to see the body displayed as "Hi ! Welcome". But, I couldn't figure out a ( simple ) way to read that employeeId and display it as "Hi ! Welcome 197040" ( i.e being able to read that variable employeeId sent from backend)
<div><h3>Hi ! Welcome {{employeeId}}</h3></div> didn't work as expected.
I am sorry if this is too basic a question, but I just couldn't see the answer anywhere.
Try this:
<div ng-init="employeeId=${employeeId}"><h3>Hi ! Welcome {{employeeId}}</h3></div>
This will assign the value of the employeeId within the context of the GSP to a variable available within the context of Angular. To understand what I mean, take a look at the generated HTML source in your browser.
By doing this, the employeeId variable will be assigned within the scope of your Angular controller also.
There is a good tutorial on using Angular with Grails here http://claymccoy.blogspot.com.au/2012/09/grails-with-angularjs-and-coffeescript.html?m=1
Your Angular app runs on the user's browser and has no access to your backend environment. Therefore simply setting employeeId as a backend environment variable does not allow Angular to access it.
I can recommend two solutions to this problem:
1) In the index view (/graph), render employeeId as a JavaScript global in a script tag. In Angular, register the global employeeId as an Angular value. Then you can inject the employeeId value into your Angular controller and render it in the Angular view.
2) Retrieve the employeeId asynchronously via Ajax before your Angular app bootstraps, and register it as an Angular value. Then you can inject it to your controller. I recently wrote a blog post about how this can be done: http://biodegreeprogrammer.blogspot.ca/2014/07/pre-loading-data-asynchronously-in.html
The other thing here is, this is gsp afterall.. and your grails variables will work as per normal like how you defined the layout..
<div><h3>Hi ! Welcome ${employeeId}</h3></div>
Which will be grails pushing that info back....
The alternative is something like this: as shown per service on this demo site..
https://github.com/vahidhedayati/testingarrested/blob/master/grails-app/assets/javascripts/testingarrested/arrestedServices.js
Maybe you wish to try out arrestedplugin for yourself as a demo and then take the for example above service and change it for your own usage..

How to load angular module

I've just started using angular and javascript and I can't really figure out how to structure my application.
I started writing a Controller and my first reflex is to put what I would call my model into a class in a different file.
I have different option
1 - putting everything (model + controller ) in one file
2 - using requireJS so my controller can 'include' my model. I've managed to do it, put it wasn't straight forward and I still have problem to make the yeoman dist version to work.
3 - use angular module, which seems to be the recommended way, but if choose this solution do I need to load explicitly my model file in the main html file. I understand that not hardcoding the dependency between files can be a good thing, so you can for example swap or change some components, but it seems wrong when for example a subclass need to requires its parent class. If I need to split a module in lots of angular submodules, do I need to load them all explicitly ? That's seem totally wrong.
Am I missing something ? what is the standard way to do so ?
What I found quite useful are the MTV meetup sessions. They give a good overview about how to apply best practices in AngularJS:
Best Practices: http://www.youtube.com/watch?v=ZhfUv0spHCY
Angular+Yeoman: http://www.youtube.com/watch?v=XOmwZopzcTA
There are many more videos on youtube. I hope this helps giving a first idea.

Categories