I'm just getting started with angularJS and struggling to figure out proper architecture for what I'm trying to do. I have a single page app but the URL always should stay the same; I don't want the user to be able to navigate to any routes beyond the root. In my app, there is one main div that will need to host different views. When a new view is accessed, I want it to take over the display in the main div. Views loaded in this way can be throw-away or stick around as hidden in the DOM - I'm interested in seeing how each might work.
I've come up with a rough working example of what I'm trying to do. See working example here in this Plunk. Basically I want to dynamically load HTML into the DOM and have standard angularJS controllers be able to hook into that new HTML. Is there a better/simpler way to do this than by using the custom directive I have here and using $compile() to hook up to angular? Perhaps there's something sort of like the router, but doesn't require URL has changes to operate?
Here's the special directive I'm using so far (taken from another SO post):
// Stolen from: http://stackoverflow.com/questions/18157305/angularjs-compiling-dynamic-html-strings-from-database
myApp.directive('dynamic', function ($compile) {
return {
replace: true,
link: function (scope, ele, attrs) {
scope.$watch(attrs.dynamic, function(html) {
if (!html) {
return;
}
ele.html((typeof(html) === 'string') ? html : html.data);
$compile(ele.contents())(scope);
});
}
};
});
Thanks,
Andy
This question is related to
javascript
angularjs
See if this example provides any clarification. Basically you configure a set of routes and include partial templates based on the route. Setting ng-view in your main index.html allows you to inject those partial views.
The config portion looks like this:
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {controller:'ListCtrl', templateUrl:'list.html'})
.otherwise({redirectTo:'/'});
}])
The point of entry for injecting the partial view into your main template is:
<div class="container" ng-view=""></div>
There is a another way also
<div id="loadhtml"></div>
step 3: in Any Controller
var htmlcontent = $('#loadhtml ');
htmlcontent.load('/Pages/Common/contact.html')
$compile(htmlcontent.contents())($scope);
This Will Load a html page in Current page
For those, like me, who did not have the possibility to use angular directive and were "stuck" outside of the angular scope, here is something that might help you.
After hours searching on the web and on the angular doc, I have created a class that compiles HTML, place it inside a targets, and binds it to a scope ($rootScope
if there is no $scope
for that element)
/**
* AngularHelper : Contains methods that help using angular without being in the scope of an angular controller or directive
*/
var AngularHelper = (function () {
var AngularHelper = function () { };
/**
* ApplicationName : Default application name for the helper
*/
var defaultApplicationName = "myApplicationName";
/**
* Compile : Compile html with the rootScope of an application
* and replace the content of a target element with the compiled html
* @$targetDom : The dom in which the compiled html should be placed
* @htmlToCompile : The html to compile using angular
* @applicationName : (Optionnal) The name of the application (use the default one if empty)
*/
AngularHelper.Compile = function ($targetDom, htmlToCompile, applicationName) {
var $injector = angular.injector(["ng", applicationName || defaultApplicationName]);
$injector.invoke(["$compile", "$rootScope", function ($compile, $rootScope) {
//Get the scope of the target, use the rootScope if it does not exists
var $scope = $targetDom.html(htmlToCompile).scope();
$compile($targetDom)($scope || $rootScope);
$rootScope.$digest();
}]);
}
return AngularHelper;
})();
It covered all of my cases, but if you find something that I should add to it, feel free to comment or edit.
Hope it will help.
I needed to execute an directive AFTER loading several templates so I created this directive:
utilModule.directive('utPreload',_x000D_
['$templateRequest', '$templateCache', '$q', '$compile', '$rootScope',_x000D_
function($templateRequest, $templateCache, $q, $compile, $rootScope) {_x000D_
'use strict';_x000D_
var link = function(scope, element) {_x000D_
scope.$watch('done', function(done) {_x000D_
if(done === true) {_x000D_
var html = "";_x000D_
if(scope.slvAppend === true) {_x000D_
scope.urls.forEach(function(url) {_x000D_
html += $templateCache.get(url);_x000D_
});_x000D_
}_x000D_
html += scope.slvHtml;_x000D_
element.append($compile(html)($rootScope));_x000D_
}_x000D_
});_x000D_
};_x000D_
_x000D_
var controller = function($scope) {_x000D_
$scope.done = false;_x000D_
$scope.html = "";_x000D_
$scope.urls = $scope.slvTemplate.split(',');_x000D_
var promises = [];_x000D_
$scope.urls.forEach(function(url) {_x000D_
promises.add($templateRequest(url));_x000D_
});_x000D_
$q.all(promises).then(_x000D_
function() { // SUCCESS_x000D_
$scope.done = true;_x000D_
}, function() { // FAIL_x000D_
throw new Error('preload failed.');_x000D_
}_x000D_
);_x000D_
};_x000D_
_x000D_
return {_x000D_
restrict: 'A',_x000D_
scope: {_x000D_
utTemplate: '=', // the templates to load (comma separated)_x000D_
utAppend: '=', // boolean: append templates to DOM after load?_x000D_
utHtml: '=' // the html to append and compile after templates have been loaded_x000D_
},_x000D_
link: link,_x000D_
controller: controller_x000D_
};_x000D_
}]);
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>_x000D_
_x000D_
<div class="container-fluid"_x000D_
ut-preload_x000D_
ut-append="true"_x000D_
ut-template="'html/one.html,html/two.html'"_x000D_
ut-html="'<my-directive></my-directive>'">_x000D_
_x000D_
</div>
_x000D_
Source: Stackoverflow.com