why templateCache not working in angular js? - javascript

I am trying to use $templateCache.But when I console using $templateCache.get() it give me undefined ..why ?
http://plnkr.co/edit/MAXQmzTVR8fpsw645rct?p=preview
<script>
angular.module('app',[ ]).directive('h',function($templateCache){
console.log($templateCache.get('about.html'))
var element=angular.element('<input type="text" ng-model="message"><div>{{message}}</div>');
return { restrict:'E',
scope:{},
templateUrl:'a.html',replace:true,
transclude:true,
compile:function(tElement){
tElement.append(element);
return function(s,e,a){
s.$watch('message',function(val){
// console.log('------'+val)
})
}
}
}
})
</script>
**console.log($templateCache.get('about.html'))** give me undefined why ?

Because currently you are running that statement while registering that directive. That time $templateCache don't have the templates in it.
You need to put that line inside directive compile function then only you will get data in it.

See this question I think this should help you
Angular Tabs render templates with caching in "ng-include src"
template is is loaded in the template cache for quick retrieval.
You can load templates by $templateCache service directly.
angular.module('app', []).run(function($templateCache) {
$templateCache.put('a.html');
});
To retrieve simply use it in your HTML
<div ng-include=" 'a.html' "></div>
or
$templateCache.get('a.html')

Related

Why does ng-click not work?

Moved this question to this post - Angular events, ng-click, do not work with other libraries Dojo, Knockout, KendoUI, ESRI JSAPI
No matter what I try, ng-click does not work. However, onclick works. Inside the scope, wiring up an on click event dos not work. What is going on?
EDIT: I can call the $scope.myClick() from the command line. But it will not hit the breakpoint. It will show an alert window, but if this is called from within HTML directive, the function is not hit.
EDIT 2: heres a plunker - https://plnkr.co/edit/kK3NmWB9wfOopG7m5MYv?p=preview
EDIT 3: Ok, so the plunker works, but the horrible application I need to add angular to must messing with something in angular. Any ideas what could be breaking Angular in an existing app? This other app uses dojo, dojo loaders, and require.js. Everything works, except for the ng-click event.
EDIT 4: I commented out an Init() call from this application which loads Dojo, Kendo UI, Knockout, and ESRI JSAPI components, and this Angular code with ng-click works. My gut feeling is knockout is messing with this. Is it possible to completely isolate Angular from the rest of this application? Any suggestions?
here is the app:
var myApp = angular.module('myApp ', []);
directive:
myApp.directive('rapidReport',
function () {
return {
restrict: 'E'
}
});
<div class="ls-rapidReports">
<div ng-app="myApp">
<div id="rapidreportCtrl" ng-controller="rrController">
<button type="button" ng-click="myClick()">hehe</button>
</div>
</div>
</div>
controller:
myApp.controller('rrController',
function rrController($scope) {
$scope.myClick = function () {
debugger;
};
});
Here is the problem:
var myApp = angular.module('myApp ', []);
which should be:
var myApp = angular.module('myApp', []); //myApp without space before '
-
EDIT: Now I see it fixed in the plnkr. If you infact try to add the space again in myApp declaration you will see the following error message in the console.
Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:nomod] Module 'myApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
As you can deduct from the error log, the app declaration in the script.js wasn't matching with the one in the ng-app directive in index.html, so the app wasn't working.

Parse content within angular directive template before rendering

Since there is no ng-url directive to use with an #import statement the way ng-src works, I am trying to create a directive for this purpose, the code is like this
.directive('importCss',
function()
{
return {
restrict: 'E',
replace: true,
scope: { loadCss : '=' },
template:'<style>' +
' #import url("{{loadCss}}")' +
'</style>',
};
}
);
The idea basically is to create HTML like this:
<style>
#import url("http://url_to_css_in_parameter")
</style>
Probably this is something very basic, but what is happening is that in my controller I have some init code that runs before asigning values to the scope var assigned to the loadCss parameter. The value is initialized to '' at the start of the controller code. The problem is that a request is made to the server requesting "http://serverAddr/{{loadCss}}" before it does the actual correct request with the values applied to the template.
Here is the callstack for the wrong request (screenshot):
Any idea while the template is being rendered before compiling and how to solve it? Thanks very much.

AngularJS ng-click not working, but ng-change is, when calling the same function

EDIT The code is all correct, the problem was because of including 'ngTouch', see my own answer below.
I am probably making some stupid mistake here, but for the life of me I cannot find it.
I have this piece of markup, which is correctly wired up with a controller:
<input type="text" ng-change="doStuff()" ng-model="stuff"/>
<button ng-click="doStuff()">doStuff</button>
The controller code:
console.log('Hi from controller');
$scope.stuff = "something";
$scope.doStuff = function() {
alert('doing stuff');
}
The problem is nothing happens when I click the button. If I change the input field, I get the alert, so ng-change works, but ng-click does not.
Let me know if this is not enough information, but I would not know what else to provide, and the general setup seems to be working fine...
The rest of the HTML does not contain any Angular directives, and it is loaded like this in myModule.config:
$stateProvider
.state('stuff', {
templateUrl: 'pages/stuff.html',
url: '/stuff',
controller: 'StuffCtrl'
})
and the controller is defined like this:
angular.module('myModule')
.controller('StuffCtrl', function ($scope) {
// above code
});
It turned out that the problem was with another dependency 'ngTouch'. I did not use it, but still it was loaded. My module did not even depend on it. (I am using that admin site template from here: http://startangular.com/product/sb-admin-angular-theme/). After removing loading of the ngTouch it worked as expected. I will file this as a bug to both projects as well... Thanks for your help!

AngularJS: How to add and compile a directive to the dom, from a service

I think what I am trying to do is fairly simple, but I can't seem to determine the correct architecture using Angular.
I'd like to have a MessageCenter, so that any controller or other piece of Angular code can add a message. I thought that the correct way to do this would be with a MessageCenter service. I would inject the service where needed, and call MessageCenter.add(). The problem that I am having is how to compile the cloned DOM directive, since $compile requires a $scope, which I do not have from a service.
Here is what I am trying. I am not sure what the correct approach is for this.
<div>
<div id="msg-proto" message-center-msg class="alert alert-success"></div>
</div>
Then:
.factory('MessageCenter', function($compile) {
var that = {}
that.add = function(type, message) {
var n = $("#msg-proto"),
n2 = n.clone();
n.parent().append($compile(n2));
}
return that;
});
And I am injecting and calling the service:
.controller('SomeCtrl', function(MessageCenter) {
MessageCenter.add('some msg');
});
I have a message-center-msg directive defined that adds some behaviors to the element. But it needs to be $compile'd in order for that to happen, and I am not sure how to make this all work. I only ever end up with "Error: Argument 'scope' is required" from the service.
How can I setup a global message center, that is able to clone/add messages and have the directive on the message dom element processed?
Your service shouldn't interact with the DOM directly as you're trying to do. If I were designing such a system I would:
Have a service which simply takes in messages and either puts them in an array (if you want to support a whole list of messages) or simply remembers the last message (if you only want to support a single message)
Have a controller which gets the message service injected to it and binds the message(s) from the service into its scope
Then have a bit of HTML (or a custom directive) that iterates the messages using the above controller and displays them
Here's what I mean (plunk here: http://plnkr.co/Eps1Gy)
index.html:
<!doctype html>
<html>
<head>
<script src="bower_components/angular/angular.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/controllers/messages.js"></script>
<script src="scripts/controllers/click.js"></script>
<script src="scripts/services/messageService.js"></script>
</head>
<body ng-app="messagesApp">
<h1>Messages</h1>
<div ng-controller="MessagesCtrl">
<ul ng-repeat="message in messages">
<li>{{message}}</li>
</ul>
</div>
<a ng-href="#" ng-controller="ClickCtrl" ng-click="addMessage()" >Add a new message!</a>
</body>
</html>
messageService.js:
function MessageService() {
this.messages = [];
this.add = function(msg) {
this.messages.push(msg);
}
}
angular.module('messagesApp')
.service('messageService', MessageService);
messages.js:
angular.module('messagesApp')
.controller('MessagesCtrl', function ($scope, messageService) {
$scope.messages = messageService.messages;
});
click.js:
angular.module('messagesApp')
.controller('ClickCtrl', function ($scope, messageService) {
var count = 0;
$scope.addMessage = function() {
messageService.add('Test message ' + count++);
}
});
app.js:
angular.module('messagesApp', [])
.config(function ($routeProvider) {
$routeProvider
.otherwise({
redirectTo: '/'
});
});
Like I said, you can replace the HTML for handling the messages with a custom directive if you want some complex interaction, but the important thing is that you don't try to muck with the view from your service. The service should interact only with a well-defined model.
I implemented something pretty identical a while back and recently made this public as a bower component.
Maybe you can use or work off of it: https://github.com/IanShoe/angular-message-center
Happy coding!
You can open your mind :)
On your call to the MessageCenter move the $scope as parameter like MessageCenter.add("", $scope);
Or ... you can expose the MessageCenter to the scope globally on startup something like this guy suggested

Using AngularJS with innerHTML

I have some AngularJS stuff that holds a bunch of arrays and data. Once a user uploads a file, the file gets parsed up and saved into the scope with its different arrays. However, after all of this and the file is held in the scope, I try to update the innerHTML, but the AngularJS code does not work. I use ng-repeat to create a table based on the arrays, but it remains a single cell with content looking like {{column}} and the like.
I have had extreme difficulty using directives and templates because my index.html says that app and module, etc, are undefined when I do something such as app.directive(...
The significant parts of my index.html file include:
<html ng-app>
... //once a file is uploaded, total.js is called;
//this was so the app didn't try to run before a file was uploaded
<div id="someStuff">This will become a table once a file is uploaded</div>
This is a simple example of how my scope is set up in total.js:
function sheet($rootScope, $parse){
$rootScope.stuff = text;
//text is a variable that contains the file's contents as a string
};
document.getElementById('someStuff').innerHTML="<div ng-controller='sheet'>{{stuff}}</div>";
The HTML changes but instead of printing the file's contents, it only prints {{stuff}}.
How can I get the innerHTML to understand that it contains AngularJS, preferably without using a partial or a directive, unless you can thoroughly explain where I'd input it and the syntax of it.
Edit 1:
I have tried using $compile but it is marked as undefined. I looked at this to figure out the compile problem, but I don't understand rtcherry's syntax, and how I should apply it to my own code.
Edit 2:
I still receive $compile undefined errors when I include it like so:
function sheet($rootScope, $parse, $compile){...};
document.getElementById('someStuff').innerHTML=$compile("<div ng-controller='sheet'>
{{stuff}}</div>")(scope);
Edit 3:
While itcouldevenbeaboat's comment was extremely unhelpful, I decided I should perhaps show you the directive way I attempted to do it.
I included this code under my sheet function:
var app = angular.module('App', []);
app.directive('spreadsheeet', function($compile){
return{
templateUrl: innerHTML.html
}
});
Where innerHTML contains <div ng-controller='sheet'>{{stuff}}</div>and on index.html I've included <div spreadsheet></div>
With this, I receive no errors, but the text does not show up, neither as {{stuff}} or as the file's contents. Even when I do something simple, such as provide template: "<h2>Hello!</h2>" instead of a templateUrl, I cannot get Hello! to print.
It works for me
document.getElementById('someStuff').innerHTML = "<div ng-controller='sheet'>{{stuff}}</div>";
$compile( document.getElementById('someStuff') )($scope);
Simple solution (it will work 100%):
In controller, don't forget to inject $document in controller as a dependency, like this:
App.controller('indiaController', function ($scope, $document,$filter, $location) {
var text_element = angular.element($document[0].querySelector('#delhi');
text_element.html('your dynamic html placed here');
}

Categories

Resources