Reputation: 9118
I have an AngularJS application that I believe is essentially pretty typical (alike many of the examples).
<html ng-app="myApp" ...
<body>
...
<div class="main" ng-view></div>
...
There's a $routeProvider
that I've set up with a whole lot of when
s to direct users to a view (template partial with a controller), such as:
$routeProvider.when('/incident/:identifier', {templateUrl:'incident.html', controller:"IncidentCtrl"});
This is all working fine. Users can go back and forth between views.
Now, let's say I have a view for an "incident". It has a form with properties of the "incident". (You can change values in the form and "Save", which is besides the point here.) I have the following requirements:
For the form that is loaded below the existing form I would like to reuse an existing template partial with its subsequent controller, which I'm already using for the top-level ng-view
elsewhere. But I've gone down a few roads to implement this at no avail; ng-include
seems to not work, as it is pretty static and does not allow for much of a lifecycle on the embedded element. Also, it seems hard to load it dynamically, which means it's gonna be loaded before the "Add work order" button is ever clicked. Could someone point me to a workable strategy? Clearly my goal is to promote reuse of existing template partial and controller, without always having the user to move between views. Much appreciated.
Edit: elaborating: I'm not happy (yet) with any ng-include
ideas that I've seen so far, since:
$routeParams
from the $routeProvider
Upvotes: 3
Views: 3170
Reputation: 42669
I would try to address your concerns with ng-include
There would be a bunch of them if I had more than just a single kind of view to embed. They would all get loaded ahead of being shown for no good reason; overkill
ng-if
can help you here. This directive would not load DOM till the condition becomes true. And it also destroys the DOM when the condition becomes false. So something like
<div ng-if='conditionwhenthepartialshouldbeshown'>
<ng-include src='templateName' ng-init='model=parent.someProperty'/>
</div>
I do not know how to parameterize the embedded views in the same way I can pass $routeParams from the $routeProvider
You can use ng-init
for passing some parameters when the view is loaded. Check documentation
I am uncomfortable of too much sharing between parent and child scopes
ng-init
can help here again. You can create a property on child scope and pass it the parent scope value in ng-init
I have no way to cleanly recreate the controller for subsequent "adds"
ng-if
does this for you.
Upvotes: 5
Reputation: 6543
The way that I found to reproduce this behavior was using Two controllers: One for your "main" view and one for your partial view.
In your controllers file
var controllers = angular.module('controllers', []);
controllers.controller('IncidentCtrl', ['$scope', function($scope) {
// Incident Ctrl Body
$scope.showForm = false;
$scope.toggleForm = function() {
$scope.showForm = !$scope.showForm;
}
}]);
controllers.controller('WorkOrderCtrl', ['$scope', function($scope) {
// Partial Form controller
// This controller can talk with $scope from IncidentCtrl
// using the $scope.$parent.$parent
$scope.save = function() {
// ...
$scope.$parent.$parent.showForm = false;
}
}]);
And your views:
<!-- incident.html -->
<button data-ng-click="toogleForm()"> Toggle Form </button>
<div data-ng-show="showForm">
<div ng-include src="'path/to/_work_order.html'"></div>
</div>
<!-- _work_order.html -->
<div data-ng-controller="WorkOrderCtrl">
<!-- view body -->
<button data-ng-click="save()"> Save </button>
</div>
Upvotes: 2