Angular way of "global controller" for Ionic apps - angularjs

I'm new to ionic and have been wondering the "angular" way of a "global controller".
In my app, I am using the starter tabs template and I want to have a bar with which I want to interact with as the user lays around in my app. And this bar would be placed in my index.html like the following.
index.html
<ion-nav-view></ion-nav-view>
<div id="my-player" class="idle">
<round-progress background-image="{{roundBg}}" background-repeat="no-repeat" background-position="center" background-size="contain" radius="23" stroke="5"></round-progress>
</div>
I want this div#my-player to be modified as the user plays around with the app.
The initial state for #my-player would be hidden, which I would do so via the css class .idle. But when the user get to my /#/tabs/replay/{:id} page and clicks on an item, I want to add a angularAudioObject and display the audio information in #my-player.
I found it very inefficient to repeat the same code over and over again all of my controllers so I wondered if there was a way to keep this audio-controlling code could be written once and not be called upon in all of my controllers.
P.S. Yes and I'm aware of services and how they could be included in my controllers but I was wondering if there is a way to keep this code "seemingly be integrated onto" my index.html file.

It doesn't really matter which file has the code in it just that the file is loaded and executed. That said you should use services or factories to define objects that you want to persist for the life of the application and for any code that would otherwise be repeated (assuming it isn't something that makes more sense as a filter or directive).
Controllers are ephemeral they are created and destroyed as you navigate views. You can have a controller outside the ui-views that could be a parent of all the other controllers but it's really a fragile way to build things. Instead take advantage of the simple DI.

Related

Best practices how to hide elements in web app using Angular

For example we have a web app and sometimes we need to hide or show some custom directives or html parts using ng-if/ng-show/ng-hide. What we do, we click on a link "Example Show Link" and our elements appear or disappear.
So, here is the Problem:
When you go to another page/state/controller of course your directive/html part is still visible.
Is there any cool solution to hide this parts?
Except using rootScope or pushing true/false flag in every controller, 'couse there could be a lot of directives and a lot of controller
You can use routes for this, and ui-router is what I think the best one that handles this. When you use routes, only the current states' templates are shown, when you navigate out of the state, its template (together with all the directives in it) are destroyed. It automatically do it for you.

How to control and react to events outside ngapp

I am trying to build an angular app on SharePoint (this question is not related to SharePoint though).
I have a page where which has a div that has angular app directive (Its a form with bunch of text boxes). The page has other components on it, which reside outside the ngapp like Ribbon control and I specifically do not have control on it.
Typically if its a jquery app, I would write document.ready function and add my custom components to the ribbon using SharePoint javascript api and wireup any events required like Save, cancel.
I would like to accomplish similar using angularjs if possible. The problem is since they reside outside ngapp I do not understand how to initialize and wire up events.
In specific I would like to know how to accomplish below.
a) Initialize ribbon buttons, which reside outside ngapp. I do not have control on specifics of html. I can only tell api to add a button on ready. In short I would like to call some code when dom is ready to initialize some UI controls that reside outside of ngapp.
b) When user clicks on that button, I would like my app to react to it.
I would like to know if its possible.
Ex:
<body>
<div>
//some area I do not have direct control over but would like to
//initialize and react to events in angular
</div>
<div ng-app="myApp">
</div>
Ok first things first.
1 initialize your ribons buttons the same way you would do it w/o the angular app, use jquery if you want, jquery and angular play well together, so no harm there
except in the buttons events add this peace of code
if using jquery
var rootScope=angular.element($('[ng-app]')[0]).scope()
this will give you the rootScope of your app and once there if you want to pass values to your app you can either attach the values to the rootScope or use
rootScope.$broadcast()
to broadcast events in any case always remember to use
rootScope.$apply()
otherwise angular will not be aware of the changes immediately.
there are other ways, using the app injector to get hold on a service or a value and make your update there,
you can also set localStorage values and have angular to watch those values. but the firs approach is the most straigt forward

how prevent angular compile specify element

I'm developing a chrome extension using angularjs (with a content script open a popup),but it meet some problem when it's parent page already use angularjs, it's parent try to compile the content inserted, so is there anyway to prevent the parent angularjs instance to compile the element I added, and the angularjs instance in extension can bootstrap the element manually ?
It's hard to answer without an example, or what is your extension flow.
Basically, angular shouldn't compile anything on it's own, it either does it when bootstrapping the app, or when you explicitly tell it to.
What I guess you are doing is have the html change before angular is loaded, and then when it loads it compiles your stuff as well.
Try adding your directives etc. after angular has finished loading on the main page (how to detect that angular finished bootstrapping is a whole other question :)).
And after you add your new element with your ng-app <div ng-app="myAngularExtensionApp"></div>, however I am not sure how it will work if it's nested inside another angular application, I don't think it will allow you to do it. If the ng-app of the main application is on the body you can add your div outside the body (weird, but legit), and it shouldn't conflict. but if it's on the html it might cause problems. (I tested it, you can bootstrap another one inside an existing app, but it can cause some really weird problems, I'd avoid it).
A bullet proof solution, that makes things a little more complicated is one I used and I like it alot:
Create an iframe on the page, which you add the angularJS script inside, and it will be your application, do not set the src of the iframe, but rather use iframe.document.open() .write(
<html><body ng-app="myExtensionApp"> etc (i.e. a complete bone structure of an angular page), now since the src is the same, you won't have same origin problems, and you can access the main page with top.
I recommend having services that will interact with the main page.
I am not sure what you want to do, but if you want a directive on the main page for example, first create it in the iframe, then move it to the main page via jquery, it will belong to YOUR angular application (since scope binding is based on prototype and the chain doesn't get broken by moving the element), it will keep reacting to changes to your scope.
However you have to remember that styles are unaffected etc.

AngularJS - Multiple controllers watching route changes

From what I've read, Angular doesn't support multiple views out of the box for URL changes.
What I really want is to have a set of controllers in charge of different parts of the application UI, that each respond in their own way to route changes.
Is there a common solution for this, or am I thinking about the application structure in the wrong way?
The ui-router plugin doesn't appear (to me) to solve this particular problem in the way I'd like - it's a state-first approach with optional URL changes, as opposed to URL-first.
Angular actually does support multiple views out of the box, what it doesn't support is multiple ng-view out of the box. You can use ng-include and place a controller on that element and watch for any route changes you need.
Essentially you'd do something like this:
<ng-include src='"menu.html"' ng-controller='MenuCtrl'></ng-include>
<div ng-view></div>
The ng-include's controller you would be watching for route changing and doing whatever is needed.
The ng-view of course is driven by the route changes setup in your app config.

General approach of left side menu that loads different content in a center of the page

I've started to learn AngularJS but I need some application design hints. Of course I'm not asking about the layout but ... how to design my application and it's controllers in a proper way. I have left sidebar with a menu that is loaded from the web using JSON. That needs a controller. That's fine. It works for me. There's a content box as well in a center of my page that loads some data dynamically. In my opinion it requires another controller.
And now comes my solution, that somehow doesn't look good IMHO. When I click a menu item in my sidebar I'm loading a content. Then I'm passing this data into a Service which emits an Event afterwards to the Second controller (which is responsible for controlling my content in a center of my page). When it receives this event it simply gets previously loaded data from the Service and displays it. It generally works.... but ... I'm pretty sure that's not the proper way of doing this.
I would be grateful for any hints. AngularJS has a really poor documentation and tutorial :(
cheers
EDIT:
OK. That's my basic application using JQuery:
http://greatanubis-motoscore.rhcloud.com/index
And that's the same application I'm converting into AngularJS:
http://greatanubis-motoscore.rhcloud.com/angular/index
No worries, some text is in Polish but... I think it really doesn't matter ;)
Note for the AngularJS version: At the moment the content is a HTML but finally it will load JSON data as the other controllers.
I would go about doing this with angular ui-router. With ui-router you can achieve this in a couple of ways. You can use nested routing to have a base state (Your sidebar menu, header etc.) which will act as your shell page, this can have its own controller as well. You could then define each of those other views as child states of the base state. These child states can also have their own controller/views as well, but they will be sitting inside the base state (both visually, and also inherit $scope properties of the base state) optionally they can have separated URLs themselves, but they don't have to, you can just change states without changing the url, by leaving the URL bit empty when you define different states in your $stateProvider configs. Another way would be to use the multiple named views feature.

Resources