angular directive does not render - angularjs

I'm having problems with angular directives. I created a custom directive but it's not appearing and i don't know why. I can access the view specified in templateUrl with using localhost.
If somebody could help me that would just be great.
Thanks.
messageListDirective.js
angular.module('neat')
.directive('message-list', function() {
return {
restrict: 'E',
templateUrl: '/views/utils/messageList.html'
}
});
messageList.html
<h4>MESSAGE LIST</h4>
And the view where I'm using the directive:
messageBoard.html
<message-list></message-list>

change directive:
.directive('message-list', function() {
to
.directive('messageList', function() {
angular normalize element tags. Read this for more info

Did you import ng-controller="neat" in your messageBoard.html ?
If yes I think you should check the url to template.

Related

Using html file in angular directive template url in mvc 5 project

I'm creating an angularJs application in MVC 5. I've created a directive as given below.
app.directive('clusterButton', function () {
return {
restrict: 'E',
scope: {
clusterInfo: '=info'
},
templateUrl: function(elem, attr){
return 'ClusterButtonTemplate';
}
};
});
I have .cshtml file named ClusterButtonTemplate.cshtml and I created a partial view method in the controller class to return this view. So the angular js directive is binding the template.
I need to remove the method in mvc controller class and need to refer the template file directly. I don't want to use a cshtml file. I need a html file for template. I have created a ClusterButtonTemplate.html file. But while setting the template as below the browser shows a 404 error.
app.directive('clusterButton', function () {
return {
restrict: 'E',
scope: {
clusterInfo: '=info'
},
templateUrl: function(elem, attr){
return 'ClusterButtonTemplate.html';
}
};
});
I didn't use angular js routing in my project. Everything is managed using the MVC routing. How can I fix this issue. Do I need to use Angular routing and MVC routing?
You'll need to put in in a place where MVC will not try to map the URL to a controller. By default, the /Content folder is ignored, so you could create a folder under it called "Templates" and use that for the URL.
templateUrl: function(elem, attr){
return '/Content/Templates/ClusterButtonTemplate.html';
You may try to use a leading slash since it's loaded using a relative path.
templateUrl: function(elem, attr){
return '/ClusterButtonTemplate.html';
}
That's very simple! Just put an html file template (as content) in the folder that you prefer (ie. app/phone-list/ in project root) then assign
templateUrl: '/app/phone-list/phone-list.template.html'
to controller templateUrl property.
Avoid the views, model or controller folders...

Using ControllerAs with a Directive

I'm trying to follow John Papa's angularJS style guide here and have started switching my directives to using controllerAs. However, this is not working. My template cannot seem to access anything assigned to vm. See this very simple plnkr example that exhibits the behavior.
http://plnkr.co/edit/bVl1TcxlZLZ7oPCbk8sk?p=preview
angular
.module('app', []);
angular
.module('app')
.directive('test', test);
function test() {
return {
restrict: 'E',
template: '<button ng-click="click">{{text}}</button>',
controller: testCtrl,
controllerAs: 'vm'
}
}
angular
.module('app')
.controller('testCtrl', testCtrl);
function testCtrl() {
var vm = this;
vm.text = "TEST";
}
When using the controllerAs syntax you don't access the $scope as you would normally, the variable vm is added to the scope, so your button needs to become:
<button ng-click="click">{{vm.text}}</button>
Notice the vm. added to the beginning of text.
Here is a fork of your Plunk with the fix applied
Q: Do you know how I would access attributes passed through as attributes to the directive, example "scope: { text: '#' }"? Am I then forced to use $scope on the controller and set vm.text = $scope.text?
A: In the article you reference, there is a section y075 that talks about just this scenario. Look into bindToController:
return {
restrict: 'E',
template: '<button ng-click="click">{{text}}</button>',
controller: testCtrl,
controllerAs: 'vm',
scope: {
text: '#'
},
bindToController: true // because the scope is isolated
};
Then you should be able to access vm.text
With "controllerAs", the controller instance alias - vm, in your case - is published on the scope as the .vm property of the scope.
So, to access its properties (i.e. the properties of the controller), you need to specify {{vm.text}} or ng-click="vm.click".
When using 'controllerAs' syntax ,as above,the scope is bound to the controller’s 'this' reference.
So it allows us to introduce a new namespace('vm' here) bound to our controller without the need to put scope properties in an additional object literal(say $scope).
So accessing anything in controller's scope,requires 'vm' namespace, as,
'<button ng-click="click">{{vm.text}}</button>'
When you use controllerAs syntax, then you have to use
bindToController: true
it will work in your directive.
I realise this ticket is quite old. I'm adding my $0.02 in case anyone stumbles on to this in the future.
Firstly, it would be nice to have some context around what you're trying to achieve, because you seem to be breaking design rules. Your directives shouldn't need to know the inner workings of your controller, or vice-versa.
I have created a simple example of how to set the caption of button in a directive. There is no need for a controller here, and I think it just makes your example difficult to follow.
var myApp = angular.module('myApp', []);
myApp.directive('myDirective', function() {
return {
scope: {
caption: "#"
},
template: '<button>{{caption}}</button>'
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp">
<my-directive caption="Hello World" />
</div>

How can I use laravel partial view by angular js in templateURL

I want to show a laravel blade view file in angular JS directive by
var commentsApp = angular.module('CommentApp',[]);
commentsApp.directive('commentForm',function(){
return {
restrict: 'EA',
replace: 'true'
templateURL: 'views/comments/comment-form.blade.php'
}
});
I want to use it by angular directive instead of
#include('comments.comment-form')
Where is my problem? How to solve this.
Thank you.
First you must define a route in laravel
Route::get('comment-form', function() {
return view('comments.comment-form');
});
Then you can use it in AngularJS
var commentsApp = angular.module('CommentApp', []);
commentsApp.directive('commentForm', function() {
return {
restrict: 'EA',
replace: 'true',
templateURL: 'comment-form'
}
});
Answer above is a good idea, however i dont like the idea of asking for a template by routing, We would create a route for each component :c . I leave my solution here:
In gulpfile.js inside elixir function add this line:
var elixir = require('laravel-elixir');
elixir(function(mix) {
mix.copy('resources/assets/js/angular/components/**/*.template.html', public/angular-templates');
//Find all files with suffix .template.html
});
As you notice it, i created a folder called 'angular' and then another one called 'components', there we will have our components
Angular-----------------------------
--Components------------------------
----my-component.directive.js-------
----my-component.template.html------
We have to create a global angular variable taking our browser window origin (www.myapp.com, localhost:8000, etc) by doing:
angular.module('myModule',[])
.value('pathAssets', location.origin + '/angular-templates/')
In our templateUrl we will call the template by writting:
templateUrl: pathAssets + '../angular-templates/my-template.html',
I have to say we have to concat our angular files in a file, otherwise it won't work D: if you don't know how to do it, add these lines in your gulpfile.js
mix.scripts([
'../../../bower_components/angular/angular.min.js',
'angular/app.js',
'angular/controllers/**/*.controller.js',
'angular/components/**/*.directive.js',
'angular/bootstrap.js',
], 'public/js/app.js'); //We concatenate angular files saving them in app.js
Finally execute the command 'gulp' in terminal(In our project), it should generate a new folder in public called angular-templates.
That's it :)
(function(angular) {
'use strict';
angular.module('app').component('bringTeamToEvent', {
templateUrl: '/assets/ng/app/team/bringTeamToEvent.html',
bindings: {
hero: '='
}
});
})(window.angular);
Just work from the public directory, no need to compile assets and move if you dont need to.
Then add the # symbol to tell blade to ignore and let angular do its work within the template
<span>Name: #{{ $ctrl.hero.name}}</span>

angularJs custom directive not working with templateUrl

I am new to AngularJs. I am writing my custom angular directive which contains a template of some html content. When I use the template with the below code it works fine.
demoApp.directive('demoCarousel', function() {
return {
restrict: 'E',
replace:'true',
template: "<h1>This is from the custom directive..</h1>"
};
});
But when I replace the template with templateUrl pointing to a html inside a partial I am getting error.
demoApp.directive('demoCarousel', function() {
return {
restrict: 'E',
replace:'true',
templateUrl: "/partials/carousel.html"
};
});
The javascript error is something like:
Error: [$compile:tplrt] http://errors.angularjs.org/1.2.15/$compile/tplrt?p0=glassCarousel&p1=%2Fpartials%2Fcarousel.html
Please let me know where I am going wrong and what the correct way to use the templateUrl
Note: I am using only pure html code inside the carousel.html file.
The error sais: Template for directive 'glassCarousel' must have exactly one root element. /partials/carousel.html
this means that you have something like this in your template:
<div>...</div>
<div>...</div>
It is not allowed, you should have one root element:
<div>
<div>...</div>
<div>...</div>
</div>

loading the angularJs directive through partial

I am new to AngularJs and struck with an issue. I have "index.html" where I need to have the main section loaded via the <div data-ng-view=""></div>. Now, the data inside the view will be populated by the controller using the below code
.when('/',
{
controller:'controllers.IndexCtrl',
templateUrl:'/partials/index-partial.html'
})
Inside the index-partial.html file I have used the custom directive linke below:
<custom-carousel/>
The code for the carousel is below:
myApp.directive('customCarousel', function() {
return {
restrict: 'E',
replace:'true',
templateUrl: "/partials/carousel.html",
link: function(scope, element, attrs) {
$('.my-list').click(function(){
$('.my-list').removeClass('active');
$(this).addClass('active');
});
}
};
});
The issue with the above approach is that the jquery code inside the directive gets called twice and hence the toggling of the selected li does not work.
I have below questions:
Is the jquery function inside the directive called twice because its called from the partial and once again during the ng-view?
Whats the reccommended way of handling this scenarios?
Whats the best approach to fix this issue. If I remove the templateUrl from the controller and directly use the custom-carousel inside the html, this works perfectly but I want to load the directive using the ng-view and not directly in the index.html file.
Please let me know the best approach to solve this issue.

Resources