AngularJs - Using ng-controller with ng-include - javascript

This works:
<div ng-include="'login.html'" flex ng-if="!loggedIn" ng-controller="LoginController"></div>
However, this doesn't ({{test}} outputs nothing):
<ng-include src="'login.html'" flex ng-if="!loggedIn" ng-controller="LoginController"></ng-include>
Is there any reason? Or is it a bug?
login.html:
<p>{{test}}</p>
LoginController:
function LoginController($scope){
$scope.test = 'login';
}

I'm not exactly sure where "loggedIn" is defined, but when I define it on a parent controller, both syntaxes work as expected.
Plunkr
<div ng-controller="PrntCtrl">
<div ng-include="'test.html'" flex ng-if="!loggedIn" ng-controller="TestCtrl"></div>
<ng-include src="'test.html'" flex ng-if="!loggedIn" ng-controller="TestCtrl"></ng-include>
</div>
Some questions to consider:
What version of angular are you using?
How is your app defined and how is the controller registered with the app?
Where is "loggedIn" defined?

Because this directive accepts only 3 arguments:
ngInclude | src = string
onload (optional) = string
autoscroll (optional) = string
...according to the ngInclude Docs
EDIT:
you can solve simply wrap it in another element...
<div ng-if="!loggedIn" ng-controller="LoginController">
<div ng-include="'login.html'" flex></div>
</div>

Related

ng-include: Access child scope issue

I'm using DayPilot Scheduler in my app and i'm having the following issue.
home.html:
<div class="container-fluid">
<daypilot-scheduler id="scheduler" daypilot-config="schedulerConfig" daypilot-events="events"></daypilot-scheduler>
</div>
I access daypilot scheduler in my controller like this:
$scope.scheduler;
This works when daypilot directive is directly inside home.html like in home.html above, but returns undefined when I include daypilot with ng-include:
<div class="container-fluid">
<div ng-include src="'partials/partial1.html'"></div>
</div>
partial1.html:
<section>
<daypilot-scheduler id="scheduler" daypilot-config="schedulerConfig" daypilot-events="events"></daypilot-scheduler>
</section>
If it's included with ng-include, $scope.scheduler returns undefined. scheduler is placed under $$childTail as $$childeTail.scheduler.
What am I doing wrong, and how can I access $$childTail?
Try adding $parent. prefix to id attribute's value. So partial1.html will be:
<section>
<daypilot-scheduler id="$parent.scheduler" daypilot-config="schedulerConfig" daypilot-events="events"></daypilot-scheduler>
</section>
And in controller access it like you always did:
$scope.scheduler;

ng-click not updating value in ng-repeat

This is the code:
<div ng-repeat="data in products">
<div class=edit ng-click="dataUI.showEdit = true; content = data;">
</div>
<div ng-repeat="renew in data.renewed">
<div class=edit ng-click="dataUI.showEdit = true; content = renew;">
</div>
</div>
</div>
<div class="modal" ng-show="dataUI.showEdit">
<div class="product_price">{{content.product_price}}</div>
</div>
When I click this, the popup opens but, the content is not filled with items. In the popup, I am using content to show the data.
What am I doing wrong here?
JSFiddle: http://jsfiddle.net/HB7LU/22082/
Here's your fiddle fixed: http://jsfiddle.net/masa671/xtaa9gev/
You were using an old version of Angular, changed to version 1.4.8 (see the JavaScript Gear).
Then, a couple of missing injections:
MyCtrl.$inject = ['$scope'];
myApp.controller('MyCtrl', MyCtrl);
Finally, assignment to content in ng-click did not work, because ng-repeat creates a new scope ("Always use a dot"). I fixed this with dataUI.content. Here is one good explanation: Ng-click doesn't work inside ng-repeat.

Angular JS ng-switch with ng-include?

I have 3 different code fragments which I'd like to swap out depending on the selection in a select menu.
It works if I include the code inline, but when I try to use ng-includes like this, I get an Angular error and the app fails:
<div ng-switch on="pFilter">
<div ng-include="'includes/parcel_details_incoming.html'" ng-switch-when="Incoming Parcels"></div>
<div ng-include="'includes/parcel_details_forward.html'" ng-switch-when="Exception Parcels"></div>
<div ng-include="'includes/parcel_details_exception.html'" ng-switch-default></div>
</div>
What am I doing wrong here? Does ng-switch not work with ng-includes?
The reason is both the directives ng-include and ng-switch-x use transclusion and you are specifying both on the same element and it is not allowed. Move nginclude to the child of ng-switch element.
<div ng-switch on="pFilter">
<div ng-switch-when="Incoming Parcels"><div ng-include="'includes/parcel_details_incoming.html'"></div></div>
<div ng-switch-when="Exception Parcels"><div ng-include="'includes/parcel_details_forward.html'"></div></div>
<div ng-switch-default><div ng-include="'includes/parcel_details_exception.html'"></div></div>
</div>
This used to work until angular 1.x version but compound transclusion will result in multidir error starting 1.2.x version of angular. Take a look at the change log and this commit.

How to use a controller outside of ngApp's scope

Due to the structure of an existing project I'm working on, I'm stuck with a template that looks like this:
<div ng-app="example">
<div ng-controller="MainCtrl" id="inner">
{{ inside }}
</div>
</div>
<div ng-controller="MainCtrl" id="outer">
{{ outside }}
</div>
#outer is supposed to be using the same controller as #inner, but as it's located outside of ngApp's scope, {{ outside }} will not be evaluated. Unfortunately I can't change the template structure, so I tried to compile #outer's content like this:
app.run(function($rootScope, $compile){
$rootScope.$apply($compile(document.getElementById('outer'))($rootScope));
});
This works, but the controller function will be executed twice, which is not desired. Is there a better way to achieve my goal?
Working example on Plunker
what you could do instead, is NOT define ng-app at all in the html, and instead bootstrap angular via javascript.
for example you can do angular.bootstrap(document, ['example']); where 'example' is the angular module for the app for example angular.module('example', [
'ngResource', 'ui.router', ....
]);
you probably defined that yourself already.
This way, you define the ng-app on the entire document scope.
That is normal, you're initializing twice the controller. You could simply create another div, wrapping all the divs you want and use alias. But this will still initialize twice, but each div will have different values, like, {{inside}} on first div will not have the same as the second one has.
<div ng-app="example">
<div>
<div ng-controller="MainCtrl as FirstCtrl" id="inner"> // alias FirstCtrl
{{ inside }}
</div>
</div>
<div ng-controller="MainCtrl as SecondCtrl" id="outer"> // alias SecondCtrl
{{ outside }}
</div>
</div>
But if you intend to use just once the same controller, as far as I'm concerned, you'll have to wrap all divs you want to use the same controller, in just one div, like:
<div ng-app="example" ng-controller="MainCtrl">
<div id="inner">
{{inside}}
</div>
<div id="outer">
{{outside}}
</div>
</div>
This will initialize just once.
Other way, could be attaching ng-app and ng-controller in your html/body tags.

AngularJS reusing the same controller on one page, with different configuration

I want to display two elements on a page controlled by different instances of the same controller, but I need to register some external information that will be unique (one "joystick" gets an identifying property set, like "player = one" while the other gets "player = two").I'm not sure of the best way of pulling this off exactly
Here's a generic example of what I'm trying to accomplish:
<!-- These need to have different configurations -->
<div ng-include src="'joystick/joy.tpl.html'"
ng-controller="JoystickCtrl">...</div>
<div ng-include src="'joystick/joy.tpl.html'"
ng-controller="JoystickCtrl">...</div>
Should I:
Use a directive?
<div ng-include src="'joystick/joy.tpl.html'"
ng-controller="JoystickCtrl" player="one">...</div>
<div ng-include src="'joystick/joy.tpl.html'"
ng-controller="JoystickCtrl" player="two">...</div>
Use $injector? (fyi - this might be an incorrect implementation)
<div ng-controller="DualJoyCtrl">
<div ng-include src="'joystick/joy.tpl.html'"
ng-controller="joyOne" player="one">...</div>
<div ng-include src="'joystick/joy.tpl.html'"
ng-controller="joyTwo" player="two">...</div>
</div>
-----
.controller('DualJoyCtrl', function ($injector, JoystickCtrl, $scope, $rootScope) {
$scope.joyOne = $injector.instantiate(JoystickCtrl, {$scope: $rootScope.$new(), player:"one"});
$scope.joyTwo = $injector.instantiate(JoystickCtrl, {$scope: $rootScope.$new(), player:"two"});
});
Or... not do this?
I realize this is similar to another, seemingly inconclusive stack post:
Edit
Since ngController is initialized before ngInit, in order to have data available in controller at once, you should wrap ngController in parent element with ngInit:
<div ng-init="player = 'one'">
<div ng-controller="JoystickCtrl">
...
</div>
</div>
Original answer
I think simple ng-init would suffice:
<div ng-controller="JoystickCtrl" ng-init="player='one'">...</div>
<div ng-controller="JoystickCtrl" ng-init="player='two'">...</div>
Store your config values in a data attribute, and retrieve it within the controller using $attrs. (The AngularJS ngInit documentation recommends to say clear of ng-init unless aliasing special properties of ngRepeat. ) A similar answer is here. This code snippet gives you the general idea:
Index.html:
<div ng-include ng-controller="JoystickCtrl" src="'same.html'" data-id="1"></div>
<div ng-include ng-controller="JoystickCtrl" src="'same.html'" data-id="2"></div>
Controller:
function joystickCtrl($scope, $attrs) {
$scope.id = $attrs.id;
};
View:
<h2>Joystick: {{id}}</h2>
Here is the full code in Plunker.

Categories

Resources