I have a LAMP website that i am trying to convert to be built on MEAN and I've split the index page into partials so i could have a SPA.
I am completely new to MEAN but i'm slowly learning and trying things however i'm now stuck on JQuery slider plugin that I am using in one of my partials and it does not load any images in the placeholder when the website is ran.
I know that i am supposed to use directives so that JQuery function is loaded after the partial page is loaded into the main page and hence why nothing is being displayed where the slider should be.
This is my partial page that contains the snippet of the slider for a single image (there are 3 of these 'li' blocks at the moment for 3 images):
home.html
<div id="pm-slider" class="pm-slider">
<ul class="pm-slides-container" id="pm_slides_container">
<li data-thumb="public/app/img/home/slide1a.jpg" class="pmslide_0"><img src="public/app/img/home/slide1.jpg" alt="img01" />
<div class="pm-holder">
<div class="pm-caption">
<h1>Medical professionals</h1>
<span class="pm-caption-decription">
that you can trust
</span>
learn more <i class="fa fa-plus"></i>
</div>
</div>
</li>
</ul>
</div>
My index.html file contains div ng-view tag where all of home.html should go.
app.js contains this code for routing and I know that here should go the .directives function for the JQuery plugin
var digiProm = angular.module('digiProm', [
'ngRoute']);
digiProm.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'public/app/partials/home.html'
})
.when('/services', {
templateUrl: 'public/app/partials/services.html'
})
.otherwise({
redirectTo: 'partials/home.html'
});
}]);
After watching multiple videos as well as tutorials i can't figure out how i should write my directive function to work.. I am trying to work out how to use this type of format
digiProm.directive('slider', ['$rootScope', function($rootScope) {
return {
restrict: 'EA',
templateUrl: '/path/to/template',
link: function(scope, iElement, attrs) {
//attrs references any attributes on the directive element in html
//iElement is the actual DOM element of the directive,
//so you can bind to it with jQuery
$(iElement).bxSlider({
mode: 'fade',
captions: true
});
}
};
}]);
Is the templateUrl here supposed to be the path to the jquery file for the slideshow?
What the heck would go inside the link: function(...) ?? This script has been shown as an example on how to use the bxSlider and i'm trying to use a Pulse PM-Slider so not sure what functions i'm supposed to call for it to load after the partial has been loaded...
Any kind of help is much appreciated.
Thank you in advance
If the directive is only activating on an element that already exists in another template then you don't need templateUrl.
That is used to be able to inject html into an element. in other words a directive can define it's own template
Also the restrict is to tell directive whether to look for E-an element , or A an attribute or C- a class.
I suggest you add an attribute since it makes it easier to see later on in the markup
<div slider id="pm-slider" class="pm-slider">
Then remove templateUrl from your directive declaration object.
Also note that when jQuery is included in page before angular.js iElement is already a jQuery object so you can just use iElement.bxslider({....})
Related
Basically I want to achieve like this scenario:
https://i.stack.imgur.com/LLTcK.png
My research led me to $compile, $trustAsHtml,at last directive.
In $compile and $trustAsHtml I can only append static template or only html but can't use dynamic things such ui-sref, ng-click etc.
So, I tried to create directive it is not working and also I am unable to add multiple template on click.
controller :
app.controller('Ctrl', ['$rootScope', '$scope',function ($rootScope, $scope)
{
$rootScope.enableDirective=false;
if(userHasOneApp){// checking some at least one app then only do action
$rootScope.appicon="img_url"; // data which i am passing
$rootScope.appname="App_name"; // data which i am passing
$rootScope.enableDirective=true;
}
}]);
custom directive:
app.directive('headerTemplate', function () {
return {
template:'<a ui-sref="/event" ng-click="editIt()">'
+'<img src="{{appicon}}"></a>'
+'<span>{{appname}}</span>',
scope:{
appname:'=',
appicon:'='
}
};
});
Header view :
<div> class="headerdiv">
<ul ng-if="enableDirective">
<li header-template appicon="appicon">
</li>
</ul>
</div>
Main view :
<div> class="maindiv">
<ui-view></ui-view> <!--basically I want to append template here -->
<button>Add next template</button>
</div>
Where I am doing wrong ?
Well i was facing the same issue
Check out the following link
This will surely help you.
I have implemented this and it worked in my scenario where i wanted to serve a directive when required i.e Lazy Loading of directive
https://www.codeproject.com/Articles/838402/Lazy-loading-directives-in-AngularJS-the-easy-way
My first question here :)
I'm porting my site to Angular (I'm new to it) and wondering if I'd be able to keep my pure CSS modal dialogue box while using ui-router. In HTML it looks like this:
<a id="footerMail" href="#openContact"></a>
<div id="openContact" class="modal">
<div class="modal__container">
X
<form class="contact-form" action="/" enctype="application/x-www-form-urlencoded" method="post">
</form>
</div>
It uses ::target on openContact id. But when I'm trying to do that while using ui-router it, obviously, doesn't allow that path to happen since it's not defined as a state. How should I define it since I don't want to redirect to a new URL just open a modal that is overlay of the current state? My $stateProvider looks like this:
$urlRouterProvider.otherwise("/site/editor");
$stateProvider
.state('site', {
url: "/site",
abstract: true,
templateUrl: "partials/site.html",
controller: 'MainController as ctrl'
})
.state('site.director', {
url: "/director",
templateUrl: "partials/gallery.html",
controller: 'GalleryController'
})
.state('site.editor', {
url: "/editor",
templateUrl: "partials/gallery.html",
controller: 'GalleryController'
});
});
The link and modal code would ideally fire from the main 'site" state since it's common for all subpages. Or maybe that's too much work and I should rewrite it and not use CSS approach?
Thanks in advance!
If your modal is always present you should just be able to use ng-show to control when it's displayed.
I typically have an application level control that I have on my body tag and have it created with something like ng-controller=AppController as app. If you had a property of this controller named showModal that you initialize as false you can have your modal created outside of the div for your ui-view and have ng-show="app.ShowModal" then in any link where you want to display the modal in the function you call from its ng-click set app.showModal to false.
There are a lot of good approaches for modals in Angular though. I've been using mdDialog from Angular Material and this one: http://www.bennadel.com/blog/2806-creating-a-simple-modal-system-in-angularjs.htm is also good. I've used the one from UI Bootstrap as well.
I worked through the tutorial on the AngularJS website and I noticed that in at step 7, they change how a controller is introduced into the application. Initially, they use a directive:
<body ng-controller="PhoneListCtrl">
...
</body>
However, it later gets changed to use a controller attribute as part of an ng-route.
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: 'PhoneListCtrl'
}).
/* rest of routes here */
Here's the git diff where the change is made. Is there a difference between these two techniques?
Controller using a ng-controller directive:
A new $scope is created on ng-controller element.
Explicit view-to-controller connection
Visible with inspect element, etc
Controller in a route:
A new $scope is created per route on the ng-view element.
The controller can request dependencies defined in the route resolve.
Optional view-to-controller connection. Recommended to have a naming convention that maps routes to controllers to views.
One of well-known feature of Angularjs is Single-Page Applications.
If you assign ng-controller attribute directly on the page:
<body ng-controller="PhoneListCtrl">
...
</body>
you can't switch controllers easily for other tasks.
So, use route to switch controllers is one of important step in learning Angular Single-Page feature.
You can have same layout and one different element by using route and ng-view directive.
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: 'PhoneListCtrl'
}).
when('/tablets', {
templateUrl: 'partials/tablet-list.html',
controller: 'TabletListCtrl'
}).
If '/phones'
<div ng-view></div>
will include your 'partials/phone-list.html' template
and set 'PhoneListCtrl' as div controller
The same:
If '/tablets'
<div ng-view></div>
will include your 'partials/tablet-list.html' template
and set 'TabletListCtrl' as div controller
This is the difference between two.
ng-view is the cause of the difference. You can't really do this
<div ng-view ng-controller="PhoneListCtrl">
As you'd need to change that controller as the route changed. So basically the router does that for you, and uses the controller you specified when you defined your routes.
You probably can do this:
<div ng-view>
and then in your template:
<div ng-controller="PhoneListCtrl">
and leave out the controller declaration in your routes. Which I suspect would have essentially the same effect, although I've never tried that. Probably better to go with convention here though.
In the 1st case the controller is directly on the page.
Once they change it, that controller is only on the page if the route is /phones otherwise it is some other controller based on some other route.
Yes - the change is this:
if you want to display a specific controller on the page, you can use
<body ng-controller>
BUT
if you want to do routing (application with more than one controller) - you will need to use routing + change the body to:
<body ng-view></body>
I'm working on two projects right now using AngularJS, and I'm running into the same problem with both of them.
The problem is that I have an index page that looks completely different from any of the inner pages, which means that my ng-view has to consist of the entire page. This makes it so that any time a route changes, the whole page has to reload instead of just the main content area. This causes things like the header or sidebar to flash briefly.
The only good approach I can think of to make my index page separate from my app is to literally have a separate, static index.html and then all my angularJS pages inside a separate folder so that I can use a more focused ng-view.
Is this the only/best approach there is? Has anyone achieved this, or have any ideas on how to? thanks.
A way to solve this problem would be using UI-Router.
For example:
You could have an app.html which is a page that holds all of your application views. In it add a:
<body>
<div ui-view></div>
</body>
and styles/scripts required by the entire application.
All of your views will go there including the index.html view.
Assuming that the pages except the index have some sort of header/body/footer layout in which the body changes according to the actual page you can use a configuration as follows:
var app = angular.module('app', [])
.config(['$stateProvider', function ($stateProvider)
{
$stateProvider
.state('index', {
url: '/index',
templateUrl: 'index.html',
controller: 'IndexController'
})
.state('root', {
templateUrl: 'root.html',
controller: 'RootController'
})
.state('root.somePage', {
url: '/some-page',
templateUrl: 'some-page.html',
controller: 'SomePageController'
})
.state('root.anotherPage', {
url: '/another-page',
templateUrl: 'another-page.html',
controller: 'AnotherPageController'
});
}
The root.html will be like a masterpage in ASP.NET Webforms so it would be in the form:
<!-- header markup here -->
<div ui-view></div>
<!-- footer markup here -->
Using the AngularJS,
I want to use ng-include to make my code generic.
So here is my problem:
I want to have my 'ang-attribute.html' file used in the ng-include to be as generic as possible, and for that I want to get the attribute name outside of the html.
With something like this:
<div data-field-name="display_name">
<div ng-include="'ang-attribute.html'"></div>
</div>
In my html file I would like to use the data-field-name, and then use it again with a different value.
I tried to get it via DOM... and couldn't find a way to do that.
So in my ng-include html file I have the following line:
<div ng-controller="attributeCtrl">
<div class="my-profile-constant-text">{{displayAttribute}}:</div>
....
</div>
Maybe there is a way to pass a constructor to the controller and then I could pass my data-field-name into it?
Or any other solution?
Thanks!
I believe you want to be looking at directives, this has an attributes object easily accessible after the dom has rendered to re-use.
Html
<my-directive field-name="display_name"></my-directive>
Directive
angular
.module("myApp", [])
.directive("myDirective", function() {
return {
restrict: "E",
template: "<div>{{exposeAttribute}}</div>",
//templateUrl: "mytemplate.html",
link: function(scope, element, attr) {
scope.exposeAttribute = attr.fieldName;
}
};
});
http://jsfiddle.net/mhCaD/