diff options
| author | Igor Minar | 2012-03-08 15:00:38 -0800 |
|---|---|---|
| committer | Igor Minar | 2012-03-08 22:29:34 -0800 |
| commit | f54db2ccda399f2677e4ca7588018cb31545a2b4 (patch) | |
| tree | 29ef2f8f834544c84cea1a82e3d08679358fb992 /src/directive/ngInclude.js | |
| parent | dd7b0f56fcd9785f7fccae8c4f088a8f3e7b125e (diff) | |
| download | angular.js-f54db2ccda399f2677e4ca7588018cb31545a2b4.tar.bz2 | |
chore(directives,widgets): reorg the code under directive/ dir
Diffstat (limited to 'src/directive/ngInclude.js')
| -rw-r--r-- | src/directive/ngInclude.js | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/directive/ngInclude.js b/src/directive/ngInclude.js new file mode 100644 index 00000000..08b14488 --- /dev/null +++ b/src/directive/ngInclude.js @@ -0,0 +1,119 @@ +'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} 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> + */ +var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile', + function($http, $templateCache, $anchorScroll, $compile) { + return { + restrict: 'EA', + compile: function(element, attr) { + var srcExp = attr.src, + scopeExp = attr.scope || '', + 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('$contentLoaded'); + } + }).error(clearContent); + } else { + clearContent(); + } + }); + }; + } + } +}]; |
