aboutsummaryrefslogtreecommitdiffstats
path: root/src/ng/directive/ngInclude.js
diff options
context:
space:
mode:
authorMisko Hevery2012-03-23 14:03:24 -0700
committerMisko Hevery2012-03-28 11:16:35 -0700
commit2430f52bb97fa9d682e5f028c977c5bf94c5ec38 (patch)
treee7529b741d70199f36d52090b430510bad07f233 /src/ng/directive/ngInclude.js
parent944098a4e0f753f06b40c73ca3e79991cec6c2e2 (diff)
downloadangular.js-2430f52bb97fa9d682e5f028c977c5bf94c5ec38.tar.bz2
chore(module): move files around in preparation for more modules
Diffstat (limited to 'src/ng/directive/ngInclude.js')
-rw-r--r--src/ng/directive/ngInclude.js131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/ng/directive/ngInclude.js b/src/ng/directive/ngInclude.js
new file mode 100644
index 00000000..90fd0b40
--- /dev/null
+++ b/src/ng/directive/ngInclude.js
@@ -0,0 +1,131 @@
+'use strict';
+
+/**
+ * @ngdoc directive
+ * @name angular.module.ng.$compileProvider.directive.ng-include
+ * @restrict EA
+ *
+ * @description
+ * Fetches, compiles and includes an external HTML fragment.
+ *
+ * Keep in mind that Same Origin Policy applies to included resources
+ * (e.g. ng-include won't work for file:// access).
+ *
+ * @scope
+ *
+ * @param {string} ng-include|src angular expression evaluating to URL. If the source is a string constant,
+ * make sure you wrap it in quotes, e.g. `src="'myPartialTemplate.html'"`.
+ * @param {Scope=} [scope=new_child_scope] optional expression which evaluates to an
+ * instance of angular.module.ng.$rootScope.Scope to set the HTML fragment to.
+ * @param {string=} onload Expression to evaluate when a new partial is loaded.
+ *
+ * @param {string=} autoscroll Whether `ng-include` should call {@link angular.module.ng.$anchorScroll
+ * $anchorScroll} to scroll the viewport after the content is loaded.
+ *
+ * - If the attribute is not set, disable scrolling.
+ * - If the attribute is set without value, enable scrolling.
+ * - Otherwise enable scrolling only if the expression evaluates to truthy value.
+ *
+ * @example
+ <doc:example>
+ <doc:source jsfiddle="false">
+ <script>
+ function Ctrl($scope) {
+ $scope.templates =
+ [ { name: 'template1.html', url: 'examples/ng-include/template1.html'}
+ , { name: 'template2.html', url: 'examples/ng-include/template2.html'} ];
+ $scope.template = $scope.templates[0];
+ }
+ </script>
+ <div ng-controller="Ctrl">
+ <select ng-model="template" ng-options="t.name for t in templates">
+ <option value="">(blank)</option>
+ </select>
+ url of the template: <tt><a href="{{template.url}}">{{template.url}}</a></tt>
+ <hr/>
+ <div ng-include src="template.url"></div>
+ </div>
+ </doc:source>
+ <doc:scenario>
+ it('should load template1.html', function() {
+ expect(element('.doc-example-live [ng-include]').text()).
+ toBe('Content of template1.html\n');
+ });
+ it('should load template2.html', function() {
+ select('template').option('1');
+ expect(element('.doc-example-live [ng-include]').text()).
+ toBe('Content of template2.html\n');
+ });
+ it('should change to blank', function() {
+ select('template').option('');
+ expect(element('.doc-example-live [ng-include]').text()).toEqual('');
+ });
+ </doc:scenario>
+ </doc:example>
+ */
+
+
+/**
+ * @ngdoc event
+ * @name angular.module.ng.$compileProvider.directive.ng-include#$includeContentLoaded
+ * @eventOf angular.module.ng.$compileProvider.directive.ng-include
+ * @eventType emit on the current ng-include scope
+ * @description
+ * Emitted every time the ng-include content is reloaded.
+ */
+var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile',
+ function($http, $templateCache, $anchorScroll, $compile) {
+ return {
+ restrict: 'EA',
+ compile: function(element, attr) {
+ var srcExp = attr.ngInclude || attr.src,
+ scopeExp = attr.scope || '',
+ onloadExp = attr.onload || '',
+ autoScrollExp = attr.autoscroll;
+
+ return function(scope, element, attr) {
+ var changeCounter = 0,
+ childScope;
+
+ function incrementChange() { changeCounter++;}
+ scope.$watch(srcExp, incrementChange);
+ scope.$watch(function() {
+ var includeScope = scope.$eval(scopeExp);
+ if (includeScope) return includeScope.$id;
+ }, incrementChange);
+ scope.$watch(function() {return changeCounter;}, function(newChangeCounter) {
+ var src = scope.$eval(srcExp),
+ useScope = scope.$eval(scopeExp);
+
+ function clearContent() {
+ // if this callback is still desired
+ if (newChangeCounter === changeCounter) {
+ if (childScope) childScope.$destroy();
+ childScope = null;
+ element.html('');
+ }
+ }
+
+ if (src) {
+ $http.get(src, {cache: $templateCache}).success(function(response) {
+ // if this callback is still desired
+ if (newChangeCounter === changeCounter) {
+ element.html(response);
+ if (childScope) childScope.$destroy();
+ childScope = useScope ? useScope : scope.$new();
+ $compile(element.contents())(childScope);
+ if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
+ $anchorScroll();
+ }
+ scope.$emit('$includeContentLoaded');
+ scope.$eval(onloadExp);
+ }
+ }).error(clearContent);
+ } else {
+ clearContent();
+ }
+ });
+ };
+ }
+ }
+}];