ngEnter(ngAnimate) class not getting added in ngDialog - angularjs

I don't know if there is a bug in ngDialog side or there is something which I am missing but I am not able to see ngEnter/ngLeave class getting added.
My ngDialog rough Html template :
<div class ="Ng-dialogBG"
ng-swipe-right="swipeRight()"
ng-swipe-left="swipeLeft()">
<div ng-show="currentID==2" class="canvas-holder" id={{currentID}}>
<avatarCanvas>
</avatarcanvas>
</div>
<div ng-show="currentID==3" class="canvas-holder" id={{currentID}}>
<avatarCanvas>
</avatarcanvas>
</div>
</div>
CSS :
.canvas-holder.ng-enter{
background-color:blue;
}
.canvas-holder .ng-leave{
background-color:black;
}
So just for testing I have used a simpler form of the code, and even then I don't see the ngEnter class being added. Swipe action changes the respective currentID in the controller to get a particular div.
PS : I have used ngSwipe, ngAnimate in my project, thus the modules have been added properly.
So is it something on the ngDialog part or am I missing someting?

Related

What's the best way for an angular controller to alter an ancestor HTML element?

I have an Angular controller which lives in a portion of the page however that application needs to get access to an HTML element that lives above it.
The best way to imagine the problem is that you have an embedded video which wants to request to be made full view-port:
<html ng-app="videoApp">
<body>
<div>
Other stuff that doesn't relate to the video player...
</div>
<div ng-controller="videoCtrl">
... stuff relating to the video controller
</div>
</body>
</html>
The exact problem is that the videoCtrl needs to be able to add a class to the body class such that it can switch the page layout to being full-page and dominated by the video.
Desired outcome, status of video app adds a "full-page" class to body tag:
<body ng-class="video.fullPage ? 'full-page', : ''">
What's would be the correct way for the video to add a class to an ancestor tag?
Under normal circumstances where the element we want to manipulate lies inside the controller that's doing the manipulation we can bind elements to variables in the scope:
<body> <!-- the videoCtrl scope is not available to <body> -->
<div ng-controller="videoCtrl">
<div ng-class="video.fullPage ? 'fullPage' : ''"></div>
</div>
</body>
However the body tag is not contained within the scope of the video controller and so has no access to the variables in its scope so we can't bind to them.
We could always reach out directly and change the class on the body using dom manipulation but that's not very Angular. What is the correct pattern for the video controller to alter the class of the body tag?
To meet a very similar requirement, I used Angular events. From the controller, $broadcast an event on $rootScope. Then have some sort of screen layout controller handle the event and toggle the possible screen configurations.
So:
child controller:
$rootScope.$broadcast('layout-action', { configuration: 'video' });
layout controller:
$scope.$on('layout-action', function(event, args) {
if (args.configuration == 'video') {
$scope.showVideo = true;
}
});
html:
<body ng-class="{'full-page': showVideo}">
*Note: this does slightly tie the child functionality to another part of the layout. However, perhaps try to generalize the video layout. For example, maybe you want a full screen mode instead.
If ng-app="videoApp" is the only parent, you could also do something on the button that would trigger the full-page class like this:
<body ng-class="{'full-page': showVideo}">
<div ng-controller="videoCtrl">
<button ng-click="$parent.showVideo = !$parent.showVideo">I'm in the video controller!</button>
</div>
</body>
In this case i'm just toggling showVideo to true or false. But like Davin said, this may not be as nice because it depends more on where it sits in the app.
See this plunkr for an example http://plnkr.co/edit/UxtA0YvCUckofAflsy9G

Jasmine-jquery, testing generated GUI for (nested) directives

I recently started using jasmine-jquery (1.3.1) together with angular (1.0.6) and need an advice on testing GUI.
I have some view for controller, which has angular directives, like 'view.html':
<div id='main-div'>
<div my-directive objects-to-iterate='someScopeObjects'>
<span id='default-span'>some default text</span>
</div>
</div>
, and in JS a directive "myDirective" is defined, having template-by-url 'myDirective.html' which includes ng-repeat and makes some nested div (row) foreach in objectsToIterate.
I load fixtures for 'view.html' and 'myDirective.html'.
Now I would like to test that during user interaction there are really some elements (rows) in 'myDirective' repeated block.
Beginning was simple:
var div = $('div#main-div');
div = $compile(div)(scope);
scope.$digest();
expect(div).toBeVisible();
And now I'm stuck. Cannot get access to "generated" source of 'myDirective' element. If I use
div.find('whatever-selector-for-element-my-directive'),
I get
<div my-directive objects-to-iterate='someScopeObjects'>
<span id='default-span'>some default text</span>
</div>
If I try to compile+digest this html against scope, I still get same markup. How could I get "generated" source, looking like (pseudo)
<div id='my-directive-content'>
<div id='object-1'>blah</div>
<div id='object-2'>blah</div>
</div>
in order to check if there are N rows visible to user?
someScopeObjects in scope exist and are valid.
And my next step is actually testing same thing for directives nested inside of 'my-directive', so I somehow have to get access to the scope of 'my-directive'. How? :)
Thank you.

Master Page Concept in AngularJS?

I would like to create master page, that is main page which will be used in all views of the application.
For example, Left navigation and top men navigation. This navigation should be displayed in all the views, whenever url changes in application.
As per ng-view, it only renders given partial view and replace previous view. In the image above all my left and top navigation should be displayed by using angular Controller.
Controller code
angular.module('modelDemo').controller("authCtrl", ['$scope', function($scope) {
$scope.list;
}]);
Please let me know, how can i achieve this
You can use angular-route or Angular-ui-router, and setting your master, following this steps:
Step 1. Make your index.html your master page.
Step 2. Add the <header>, <footer>, <aside>, <div>, etc. referencing your templates by using ng-include
NOTE: your left and top navigation will be part of it
Step 3. The content of the view will be rendered using the directive attribute ng-view or ui-view
Step 4. Use your module app.config() to configure the children pages
Source:
using Angular Route: https://docs.angularjs.org/tutorial/step_07
template for a brand-new app: https://github.com/angular/angular-seed
using Angular UI Router: Angular Tutorial 30 mins
ng view should be able to do that just fine. Keep your top navigation / left navigation html intact and use ng view for the various display area. http://docs.angularjs.org/api/ng.directive:ngView
To use the controller from the top navigation inside ng-view you can use $parent to get access to that scope : https://stackoverflow.com/a/14700326/390330
Fiddle for parent scope : http://jsfiddle.net/ezhrw/2/
<button ng:click="$parent.letter = greek">Assignment expression {{ greek }}</button>
I was trying to create the same concept, but needed a way to define placeholders. I started experimenting in Plnkr.co and thus far, I resorted to using a LayoutManager that drives itself from settings within the routeProvider object.
Here is an example: http://embed.plnkr.co/4GPDfTSQCuqukJE7AniZ/
You'll see an example of how multiple routes use the same header and footer, I did not include an example with a sidebar.
Let me explain the LayoutManager.
I wanted to have placeholders that could be overridden. In this example, I have a toolbar that contains a title and provides a space to the right of the title for additional toolbar items. This gives views an opportunity to throw in additional functionality.
All of this is driven by the LayoutManager. The LayoutManager is a service that reads layout properties set on the $routeProvider. I wanted to implement this in a way keep things clean and self contained, per route. The LayoutManager is injected into the toolbar directive. The toolbar directive drives it's scope properties of the LayoutManager.
In turn, the LayoutManager has a dependency on the routeProvider as well as the rootScope $routeChange event.
I'm very new to Angular, open to suggestions.
I could not see any problem, if you are using bootstrap then use can easily divide your screen as you want
<div class="row">
<div class="col-lg-3">
Left panel
</div>
<div class="col-lg-9" style="border:1px solid #999; overflow-y:auto">
<div> Top Banner </div>
<!-- Main view to render all the page -->
<div ui-view> </div>
</div>
</div>
If you want complete demo and code on then see this link
Edited: 3 Nov. 2016:
If you are using ui-router then we can user abstract state to create different master pages.
You don't need to play show/hide, ng-if but just define the routing properly with you master pages and child pages
Better to see the detail
I know this is an old thread, but thought it should be noted that as of Angular 1.5+ we have been introduced to components. Instead of dealing with routes with named views and all that nonsense or using ngInclude you should be using a header component and footer component. Simply add these to your index.html (or whatever you call your master html template) and voila.
For example (this is using Angular Material and is missing the layout module but hopefully you get the point)
1. Added to index.html
<layout-header></layout-header>
2. header.component.js (you don't need all of this but I think it's helpful)
(function () {
'use strict';
angular
.module('layout')
.component('layoutHeader', {
templateUrl: 'layout/header.html',
bindings: {},
controller: Controller
});
Controller.$inject = [];
function Controller() {
var ctrl = this;
initialize();
////////////////////
function initialize(){
}
}
}());
3. header.html
<md-toolbar>
<div class="md-toolbar-tools">
<h2>
<span>Really Awesome Title!!!!</span>
</h2>
<span flex></span>
<md-button class="md-icon-button" aria-label="More">
<md-icon class="material-icons">more_vert</md-icon>
</md-button>
</div>
</md-toolbar>

How to write a directive which can render some html code with angular directives, and show it as text?

I think some sample code can explain my purpose.
Some html code with angular:
<div ng-init="buttons=['add','edit','delete']">
<div show-result-as-text>
<button ng-repeat="button in buttons">{{button}}</button>
</div>
</div>
You can see there is a custom directive "show-result-as-text" which I want to define. It should render the inner html code with angular directives, then show them as text.
The final html should be:
<div ng-init="buttons=['add','edit','delete']">
<div show-result-as-text>
<button>add</button>
<button>edit</button>
<button>delete</button>
</div>
</div>
And when the buttons value changes, the escaped html should also be changed.
I've tried to write one myself, but failed after 2 hours of work.
UPDATE
A live demo: http://plnkr.co/edit/fpqeTJefd6ZwVFEbB1cw
The closest thing I could think of is exemplified here: http://jsfiddle.net/bmleite/5tRzM/
Basically it consists in hiding the src element and append a new element that will contain the outerHTML of each src child.
Note: I don't like the solution but it works, so I decided to share it...

How to open an angularjs page as a popup from another angularjs page

I have 2 CakePHP pages. Both of them use angularjs. Here's a snippet.
/items/items.ctp
<div id="ng-app" ng-app>`
<div ng-controller="ItemController">
Add
</div>
</div>
the function showAddPopup is defined as follows
$scope.showAddPopup = function() {
$.colorbox({href:'/items/add/' + $scope.order.id,open:true,close : "x", onClosed:function(){}});
}
/items/add.ctp
<div id="ng-app" ng-app>`
<div ng-controller="AddController">
<h2>{{order.label}}<h2>
</div>
</div>
Now, when I click on the add link from items view, I get a popup with the contents of add.ctp. But the problem is that instead of showing order label say 'My Order', the h2 tag is showing {{order.label}}
When I open add view from a page that doesn't use angularjs I get a proper result. What am I doing wrong. Please help. I have already wasted many days on this.
Maybe opening the colorbox with setting iframe could be the solution, if the problem is nested ng-apps.
$.colorbox({inline:false; iframe:true;href:'/items/add/'...});
If you are using bootstrap then angular-ui would be a great choice for above scenario

Resources