My problem is, when Angular load templateUrl (through $routeProvider) inside ng-view it doesn't evaluate all javascript as well. I tried to figure it out, but now i'm really confused. During my search i found a lots of new topic, and i've lost in them. Any idea?
Tale
I tried to figure it out if anybody else met this problem before, or if there are any solution for this problem. The way i've found was something like "lazy-loading" directives or using requirejs, but i'm not sure if those tools are really solves this problems.
As Buu Nguyen mentioned in this thread
That's the way jqLite works. If you want scripts in templates to be
evaluated, include jQuery before AngularJS. If jQuery is included, the
script will be evaluated. Try removing jQuery, and you see the
originally observed behavior.
I've tried, including jquery before angularjs but doesn't cause any effect at all.
There are sevaral threads i read, for example
stack-overflow-19434249
stack-overflow-12197880
stack-overflow-21994037
but nothing lead to solution (maybe i've missed a thing). And i think, this is not even my problem. I don't want to (re)load javascript files, i just want to force evaluate my bootstrap.
Honestly i'm really confused now.
Afterward first time i met RequireJS. (lazy loading, and friends, again)
I've watched Thomas Burleson's video on youtube and i nearly understand what is it. And i looked much more articles in topic (because i found it's interest) but solution should be somewhere else.
Here is the situation
While i'm working on my angularjs app, i've made a partial site as separated .html file (just in case) and it seems pretty. Then i cut this .html file to pieces (header, top-menu, content, footer) and use its body tag as div inside a partial urlTemplate.
<body ng-app="myApp" id="page-top">
<div class="wrapper">
<div class="navigation">
<div top-menu></div>
</div>
<div ng-view></div>
<footer id="page-footer">
<div class="container">
<span>Copyright © 2014. All Rights Reserved.</span>
<span class="pull-right">Go to top</span>
</div>
</footer>
</div>
</body>
angular $routeprovider:
angular.module('myApp').config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'main/templates/main.html'
}).when('/ad-element', {
templateUrl: 'submit/templates/submit.html'
}).when('/404', {
templateUrl: 'errors/templates/404.html'
}).otherwise({
redirectTo: '/404'
});
}]);
submit.html
<div class="page-sub-page page-submit">
<div ng-controller="SubmitController" class="container">
<form ...></form>
</div>
</div>
Every angular function is working, the only visible difference is the appearance.
This is the good one:
And this is the bad one:
Related
I'm trying to include some HTML on my software's webpage using ng-include, and I can't seem to get it to work. For now, I am using simplified versions of my end goals for testing purposes.
Relevant snippet of my project tree:
-web
--dragonweb
---src
----app
-----dragon
-------dragon.css
-------dragon.html
-------dragon.spec.ts
-------dragon.ts
-------test.html
dragon.html
<div ng-app = "" ng-controller="test">
testing
<div ng-include="" src="'app/src/dragon/test.html'"></div>
</div>
test.html
<div>
This is an included file
</div>
Expected output on the web page:
testing
This is an included file.
Actual output on the web page:
testing
I've tried using different lengths of the path to test.html, with no luck. I've also been playing around with the use of the ng-controller tag, and syntax for the ng-include tag, with no luck. There are no console errors in the web page. Any idea why it doesn't seem to be working?
Backstory/disclaimer: I was the intern on this project before inheriting it after the lead dev suddenly left, this is my first time doing any sort of web development, and I'm just learning on the job from trial and error. So if I'm doing things wildly incorrect, I am absolutely all ears for how I can improve this process! I chose to try to use ng-include because we already have Angular implemented, and based on my research this seemed like the theoretically easiest way to accomplish what I wanted.
You need to pass the src to ng-include directive not the src attribute:
Ex:
<div ng-include="'app/src/dragon/test.html'"></div>
or use relative path:
<div ng-include="'./test.html'"></div>
Please check out the official documentation for details
Usage:
as element:
<ng-include
src="'string_url'">
...
</ng-include>
as attribute:
<ANY_ELEMENT_TAG
ng-include="'string_url'">
...
</ANY_ELEMENT_TAG>
as CSS class:
<ANY class="ng-include: string; [onload: string;] [autoscroll: string;]"> ... </ANY>
I have a file index.html with the following code:
<div ng-include="'fragment-1.html'"></div>
The code of fragment-1.html:
<b>Inside Fragment 1</b>
<script type="text/javascript">
alert("Inside Fragment 1");
</script>
When I load index.html into the browser, output is:
Inside Fragment 1
The DOM has the <script> tags but the alert is not shown.
My hypothesis:
Because the DOM loads first along with the Angular modules and then Angular checks and binds the data(in this case, fragment-1.html file content) to the view(index.html), it just adds the elements of fragment-1.html in DOM. To execute the JS inside fragment-1.html, we should create a hack for it. Am I right in this explanation? Or is there something else that I may be missing?
I had to load jQuery before loading Angular. The explanation is in the link specified above. Explanation: script not running in templateurl
To include another partial HTML file in your parent HTML file, one can also use Angular directives, depending on the situation. See this answer for when to use ng-include and when to use directives: https://stackoverflow.com/a/24172025/3132646
You don't need to hack. Angular gives you a neat and simple solution to what you want to achieve with your code.
Controller
.controller('fragmentOneCtrl', function ($scope) {
alert('"Inside Fragment 1"');
})
View
<div ng-repeat="go in ['go', 'gogo']" ng-include="'includeThis'">
</div>
<script type="text/ng-template" id="includeThis">
<div ng-controller="fragmentOneCtrl">
</div>
</script>
You may want to use $sce.trustAsHtml before injecting the resource in html
I've noticed a strange behavior of ng-include -- it is causing a strange side effect on the browser in some cases.
Here is a page, that contains a simple twitter bootstrap tab pane
<body>
<ul class="nav nav-tabs">
<li class="active">Tab 1</li>
<li>Tab 2</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">AAA</div>
<div class="tab-pane" id="tab2">BBB</div>
</div>
</body>
Now, if I add ng-include anywhere in the page, for example at the beginning of the page:
<body>
<ng-include src="'page1.html'"></ng-include>
...
It doesn't matter what the included file contains, it can be even empty, but this will cause each click when switching tabs to add #/tab1, #/tab2, etc. to the page URL. This happens in all browsers, which is undesirable. On Chrome, this also causes the tab icon to flicker, and for a moment it shows default white icon before it reloads the page specific icon.
Anyone experienced something similar? Why adding ng-include would cause this?
I also tried doing the include without angular (by using jQuery.load()) and there is no issue seen.
This can be fully experienced on a standalone page, but on this plnkr page I created, although one cannot see the URL, and the flicker effect in Chrome is less visible, but still the effect can be seen in Chrome.
The url changing behavior come from the $location service, which is used by ng-include. So you could be able to reproduce it by just injecting the $location service somewhere in your app.
See the What does it do? section of this $location guide, and the action that causing the problem is:
Maintains synchronization between itself and the browser's URL when the user clicks on a link in the page
This answer your question "Why adding ng-include would cause this?".
To prevent the url from changing by the $location service, you could do it like this:
appModule.run(function ($rootScope) {
$rootScope.$on('$locationChangeStart', function ($event, newUrl, oldUrl) {
// may add some logic here to prevent url changes only that come from clicking tab.
$event.preventDefault();
});
})
Example plunker: http://plnkr.co/edit/4289uwL1mHSRj6oP4dl1?p=preview
Hope this helps.
I'm using Angular JS and Angular IU-Router in my project and using a lot of ui-views. I have a situation where I need to change the language of the site, therefore I need to swap my ui-view's model to another model with the relevant language. I already have a service that detects the relevant model and passes it into the ui-view's controller. So if I can reload the ui-view, then in theory my problem would be solved.
I recall reading something about automatically reloading a ui-view (or possibly an ng-view) and re-instantiating its controller, but after much searching I haven't been able to find that information again.
Does anyone know what it is I'm looking for?
1 Take a look at angular-translate
https://github.com/PascalPrecht/angular-translate
2 In your case, add some if-else control ( ng-if, ng-switch etc. ) in the outer div, use the same subview in the inner div. Then change the settings.currentLang when the language changes may cause the subview reload (not tested).
<div ng-controller="containerCtrl">
<div ng-if="settings.currentLang=='en'">
<div ui-view='subview'></div>
</div>
<div ng-if="settings.currentLang=='ja'">
<div ui-view='subview'></div>
</div>
</div>
I have a directive which loads content from an external HTML file. Passed into this directive is some scope data which is used in the rendering of that HTML fragment. e.g.
<div class="{{cls}}" data-obj="{{obj}}" data-id="{{id}}">
<!-- remainder of content here -->
</div>
What I would like to do within this directive is to load a further HTML partial within this based on the original scope data passed into the directive. I can't seem to get this to work, but it should be something along the lines of the following:
<div class="{{cls}}" data-obj="{{obj}}" data-id="{{id}}">
<!-- remainder of content here -->
<div ng-include="partials/{{obj}}.html></div>
</div>
Using this, the file doesn't get included, but I don't get any errors either. Can anybody assist me here?
NB: I read this, which is a similar issue, but hasn't helped me.
UPDATE - I noticed in Chrome dev tools that the URL is being resolved as expected, but the file contents are not getting included. I thought from the docs that ng-include loaded and compiled the requested fragment, so I was expecting this to work.
Found a solution in the end, by declaring the following in the directive:
<div ng-include src="view.getView()"></div>
and the following in the directive controller:
$scope.view = {
getView: function() {
return "partials/" + $scope.obj + ".html";
}
};
Works perfectly now!
In comment on the comment of Shane Gadsby: it is not <div ng-include src="'partials/'+{{obj}}+'.html'"></div> but <div ng-include src="'partials/'+obj+'.html'"></div>.
Your comment explains why 'this is what you need to force it from object literals to a string', so everything not in single quotes is handled by the compiler as a scope object.