I have a very strange behavior in an AngularJS app: I am registering routes using the $routeProvider. This works perfectly unless I embed an ng-include element BEFORE the ng-view.
Currently I have two options to fix it:
Move the ng-include to a place after the ng-view element.
Wrap the ng-include inside a <div> element.
Any idea what might cause this issue?
Try it as
<div ng-controller="MainCtrl" ng-include src="template">
angular.module('App')
.controller('MainCtrl',['$route','$scope', function($route,$scope){
$scope.template= 'main.html';
}]);
In main.html, place the ng-view tag.
In this case, you need to handle ng-include with the controller and inject $route as dependency.
i too had some issues with the $route.
one idea that solved my problems was to just use ng-switch for the ng-include instead of ng-view
Conditional ng-include in angularjs
Related
I've got a list of pop-ups/dialogs (enclosed in divs) that I want to place in a single HTML file and from there reference in different directives representing those pop-ups. As far as I know, AngularJS directive's templateUrl normally reference an HTML file. Is it possible to reference a single div within HTML for templateUrl? If it is, how to do it?
If your template fragments are small, you can reference them from within your JS by using the template: parameter instead of templateUrl:. However, in my projects, I reference all the template partials by templateUrl and use a grunt task to preload all the individual HTML files into one Javascript file that is then loaded by Angular into the template cache. You can read more about it here.
You can do the following:
Add the div's as a <script> and add the attributes type="text/ng-template" and id="", then when you set the templateUrl:, you pass the id from the script element.
Example:
HTML:
<script type="text/ng-template" id="template/awesomeDiv.html">
<div>
(...)
</div>
</script>
Directive:
templateUrl: 'template/awesomeDiv.html'
NOTE:
In order to use this, you need to have nested directives, so the parent directive includes your HTML with all divs, and the children uses the ng-template'd divs
I had the intention to use one template across several views having different controllers.
But now I realize that I cannot just write universal binding in templates because values will be put inside $scope.concreteControllerName.
Angular docs for ngInclude say that
This directive creates new scope.
I could use ng-init directive and pass controller instance to template's scope:
<ng-include src="..." ng-init="controller=concreteControllerName"/>
or even better
<ng-include src="..." ng-init="model=getModelForTemplate()"/>
and then write {{controller.boundvalue}} in template.
That is a working solution, I guess.
And here I'd like to know whether other better approaches exist and if not, should templates always be used with some notion of passed model to abstract away from parent scope?
Use John Papa's controllerAs View Syntax and controllerAs with vm. You specify different controllers in the ng-include directives but use the same src html template. The common vm variable name is used in the template.
index.html
<div ng-include ng-controller="controllerOne as vm" src="'same.html'"></div>
<div ng-include ng-controller="controllerTwo as vm" src="'same.html'"></div>
<div ng-include ng-controller="controllerThree as vm" src="'same.html'"></div>
controllerOne.js
function controllerOne() {
var vm = this;
vm.name = 'Controller One!';
sharedTemplate.html
<div>{{vm.name}}</div>
Here is a full working version: Full Working Code in Plunker
I'm using angular 1.1.5 with ngInclude in my template. Whenever I load the page I get a duplicate path after the hashbang: http://localhost/home#/home, http://localhost/account#/account, etc. This happens when there's ngInclude directive in the page (I think this also happens with ngView). I'm not using any routing with this app, and it's a very simple setup overall.
Using $locationProvider.html5Mode(true) in the module configuration seems to resolve this, but I don't want to use that as it doesn't really fit with this application's design.
This doesn't seem to happen in angular 1.2.0-RC.2, but I don't want to migrate just yet. Any known workarounds? thanks.
Use a function as the value:
app.controller("foo", function($scope) {
$scope.url = function() {
return "/bar";
}
});
<div ng-controller="foo">
<ng-include src="url()"></ng-include>
</div>
I've a two directives with transcluding html which calls isolated scope.
This Plnkr works fine while templates are inline, but if I change template to templateURL, it stops work.
Are there any issues with compiling?
Loading the template use URL, Angularjs creates an additional transcluded scope I guess.
Try to use $$prevSibling.$$prevSibling to access the functions.
Btw, it is really hacky to use $$prevSibling.
<div authorization>Sign in</div>
<div registration>Registration</div>
When trying to add an ng-view inside an ng-include, nothing happens. e.g. in the following code, when themes/midnight/index.html holds an ng-view, no view is rendered:
<ng-include src="'themes/midnight/index.html'"></ng-include>
However, if I use the code below, the view shows twice:
<ng-include src="'themes/midnight/index.html'"></ng-include>
<div ng-view></div>
What is the problem and how can I resolve it?
This problem occurs due a delayed instantiation of ng-view (passing through ng-include). In such case the $route instantiation is delayed as well, and $route will miss the location change event (and routing will not be performed at all).
To bypass this, invoke the $route update function on application initialization:
yourApp.run(['$route', function($route) {
$route.reload();
}]);
Further more, it is sufficient to only include $route as a dependency. This will work, too:
yourApp.run(['$route', angular.noop]);
Source: the related issue on github.
Also check out ui-router, which is intended to specifically deal with the issue of nested views.