Skip to content

Commit 945056b

Browse files
committed
linking function should return bound scope
angular.compile()() returns {scope:scope, view:view}, this isn't useful at all and only makes tests more verbose. Instead, this change makes the linking function return scope directly and if anyone needs the linked dom there are two ways to do it documented in angular.compile. other changes: - moved angular.compile docs to the compiler so that they are closer to the compiler - fixed some typos and updated angular.compile docs with the new return value
1 parent 128feb2 commit 945056b

14 files changed

Lines changed: 362 additions & 336 deletions

docs/guide.bootstrap.ngdoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ equivalent to the code in the previous section.
5050
(function(window, previousOnLoad){
5151
window.onload = function(){
5252
try { (previousOnLoad||angular.noop)(); } catch(e) {}
53-
angular.compile(window.document).$init();
53+
angular.compile(window.document)();
5454
};
5555
})(window, window.onload);
5656
</script>

src/Angular.js

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -774,55 +774,7 @@ function merge(src, dst) {
774774
}
775775

776776

777-
/**
778-
* @workInProgress
779-
* @ngdoc function
780-
* @name angular.compile
781-
* @function
782-
*
783-
* @description
784-
* Compiles a piece of HTML string or DOM into a view and produces a linking function, which can
785-
* then be used to link {@link angular.scope scope} and the template together. The compilation
786-
* process walks the DOM tree and tries to match DOM elements to {@link angular.markup markup},
787-
* {@link angular.attrMarkup attrMarkup}, {@link angular.widget widgets}, and
788-
* {@link angular.directive directives}. For each match it executes coresponding markup, \
789-
* attrMarkup, widget or directive template function and collects the instance functions into a
790-
* single linking function which is then returned. The linking function can then be used
791-
* many-times-over on clones of compiled DOM structure, (For example when compiling
792-
* {@link angular.widget.@ng:repeat repeater} the resulting linking function is called once for
793-
* each item in the collection. The `ng:repeat` does this by cloning the template DOM once for
794-
* each item in collection and then calling the linking function to link the cloned template
795-
* with the a new scope for each item in the collection.)
796-
*
797-
<pre>
798-
var mvc1 = angular.compile(window.document)();
799-
mvc1.view; // compiled view elment
800-
mvc1.scope; // scope bound to the element
801-
802-
var mvc2 = angular.compile('<div ng:click="clicked = true">click me</div>')();
803-
</pre>
804-
*
805-
* @param {string|DOMElement} element Element or HTML to compile into a template function.
806-
* @returns {function([scope][, cloneAttachFn])} a template function which is used to bind element
807-
* and scope. Where:
808-
*
809-
* * `scope` - {@link angular.scope scope} A scope to bind to. If none specified, then a new
810-
* root scope is created.
811-
* * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the
812-
* `template` and call the `cloneAttachFn` allowing the caller to attach the
813-
* clonned elements to the DOM at the approriate place. The `cloneAttachFn` is
814-
* called as: <br/> `cloneAttachFn(clonedElement, scope)`:
815-
*
816-
* * `clonedElement` - is a clone of the originale `element` passed into the compiler.
817-
* * `scope` - is the current scope with which the linking function is working with.
818-
*
819-
* Calling the template function returns object: `{scope:?, view:?}`, where:
820-
*
821-
* * `view` - the DOM element which represents the compiled template. Either same or clone of
822-
* `element` specifed in compile or template function.
823-
* * `scope` - scope to which the element is bound to. Either a root scope or scope specified
824-
* in the template function.
825-
*/
777+
/** @name angular.compile */
826778
function compile(element) {
827779
return new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget)
828780
.compile(element);

src/Compiler.js

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,76 @@ Template.prototype = {
7171
///////////////////////////////////
7272
//Compiler
7373
//////////////////////////////////
74+
75+
/**
76+
* @workInProgress
77+
* @ngdoc function
78+
* @name angular.compile
79+
* @function
80+
*
81+
* @description
82+
* Compiles a piece of HTML string or DOM into a view and produces a linking function, which can
83+
* then be used to link {@link angular.scope scope} and the template together. The compilation
84+
* process walks the DOM tree and tries to match DOM elements to {@link angular.markup markup},
85+
* {@link angular.attrMarkup attrMarkup}, {@link angular.widget widgets}, and
86+
* {@link angular.directive directives}. For each match it executes coresponding markup, \
87+
* attrMarkup, widget or directive template function and collects the instance functions into a
88+
* single linking function which is then returned. The linking function can then be used
89+
* many-times-over on clones of compiled DOM structure, (For example when compiling
90+
* {@link angular.widget.@ng:repeat repeater} the resulting linking function is called once for
91+
* each item in the collection. The `ng:repeat` does this by cloning the template DOM once for
92+
* each item in collection and then calling the linking function to link the cloned template
93+
* with the a new scope for each item in the collection.)
94+
*
95+
<pre>
96+
var mvc1 = angular.compile(window.document)();
97+
mvc1.view; // compiled view elment
98+
mvc1.scope; // scope bound to the element
99+
100+
var mvc2 = angular.compile('<div ng:click="clicked = true">click me</div>')();
101+
</pre>
102+
*
103+
* @param {string|DOMElement} element Element or HTML to compile into a template function.
104+
* @returns {function([scope][, cloneAttachFn])} a template function which is used to bind element
105+
* and scope. Where:
106+
*
107+
* * `scope` - {@link angular.scope scope} A scope to bind to. If none specified, then a new
108+
* root scope is created.
109+
* * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the
110+
* `template` and call the `cloneAttachFn` function allowing the caller to attach the
111+
* cloned elements to the DOM document at the approriate place. The `cloneAttachFn` is
112+
* called as: <br/> `cloneAttachFn(clonedElement, scope)`:
113+
*
114+
* * `clonedElement` - is a clone of the original `element` passed into the compiler.
115+
* * `scope` - is the current scope with which the linking function is working with.
116+
*
117+
* Calling the template function returns the scope to which the element is bound to. It is either
118+
* a new root scope or scope passed into the template function.
119+
*
120+
* If you need access to the compiled view, there are two ways to do it:
121+
*
122+
* - either create the DOM element(s) before you send them to the compiler and keep this reference
123+
* around. This works if you don't need the element to be cloned by the link function.
124+
* <pre>
125+
* var view = angular.element('<p>{{total}}</p>'),
126+
* scope = angular.compile(view)();
127+
* </pre>
128+
* - if on the other hand, you need the element to be cloned, the view reference from the original
129+
* example would not point to the clone, but rather to the dom that is cloned. In this case,
130+
* you can access the clone via the cloneAttachFn:
131+
* <pre>
132+
* var original = angular.element('<p>{{total}}</p>'),
133+
* scope = someParentScope.$new(),
134+
* clone;
135+
*
136+
* angular.compile(original)(scope, function(clonedElement, scope) {
137+
* clone = clonedElement;
138+
* //attach the clone to DOM document at the right place
139+
* });
140+
*
141+
* //now we have reference to the cloned DOM via `clone`
142+
* </pre>
143+
*/
74144
function Compiler(markup, attrMarkup, directives, widgets){
75145
this.markup = markup;
76146
this.attrMarkup = attrMarkup;
@@ -97,15 +167,15 @@ Compiler.prototype = {
97167
// important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
98168
// and sometimes changes the structure of the DOM.
99169
var element = cloneConnectFn
100-
? JQLitePrototype.clone.call(templateElement) // IMPORTAN!!!
170+
? JQLitePrototype.clone.call(templateElement) // IMPORTANT!!!
101171
: templateElement;
102172
scope = scope || createScope();
103173
element.data($$scope, scope);
104174
scope.$element = element;
105175
(cloneConnectFn||noop)(element, scope);
106176
template.attach(element, scope);
107177
scope.$eval();
108-
return {scope:scope, view:element};
178+
return scope;
109179
};
110180
},
111181

test/AngularSpec.js

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -369,45 +369,51 @@ describe('angular', function(){
369369
});
370370

371371
describe('compile', function(){
372-
var mvc;
372+
var scope, template;
373+
373374
afterEach(function(){
374-
dealoc(mvc.view);
375+
dealoc(scope);
375376
});
376377

377378
it('should link to existing node and create scope', function(){
378-
mvc = angular.compile('<div>{{greeting = "hello world"}}</div>')();
379-
expect(mvc.view.text()).toEqual('hello world');
380-
expect(mvc.scope.greeting).toEqual('hello world');
379+
template = angular.element('<div>{{greeting = "hello world"}}</div>');
380+
scope = angular.compile(template)();
381+
expect(template.text()).toEqual('hello world');
382+
expect(scope.greeting).toEqual('hello world');
381383
});
382384

383385
it('should link to existing node and given scope', function(){
384-
var scope = angular.scope();
385-
mvc = angular.compile('<div>{{greeting = "hello world"}}</div>')(scope);
386-
expect(mvc.view.text()).toEqual('hello world');
387-
expect(mvc.scope).toEqual(scope);
386+
scope = angular.scope();
387+
template = angular.element('<div>{{greeting = "hello world"}}</div>');
388+
angular.compile(template)(scope);
389+
expect(template.text()).toEqual('hello world');
390+
expect(scope).toEqual(scope);
388391
});
389392

390393
it('should link to new node and given scope', function(){
391-
var scope = angular.scope();
392-
var template = jqLite('<div>{{greeting = "hello world"}}</div>');
394+
scope = angular.scope();
395+
template = jqLite('<div>{{greeting = "hello world"}}</div>');
396+
393397
var templateFn = angular.compile(template);
394398
var templateClone = template.clone();
395-
mvc = templateFn(scope, function(clone){
399+
400+
templateFn(scope, function(clone){
396401
templateClone = clone;
397402
});
403+
398404
expect(template.text()).toEqual('');
399-
expect(mvc.view.text()).toEqual('hello world');
400-
expect(mvc.view).toEqual(templateClone);
401-
expect(mvc.scope.greeting).toEqual('hello world');
405+
expect(scope.$element.text()).toEqual('hello world');
406+
expect(scope.$element).toEqual(templateClone);
407+
expect(scope.greeting).toEqual('hello world');
402408
});
403409

404410
it('should link to cloned node and create scope', function(){
405-
var scope = angular.scope();
406-
var template = jqLite('<div>{{greeting = "hello world"}}</div>');
407-
mvc = angular.compile(template)(scope, noop);
411+
scope = angular.scope();
412+
template = jqLite('<div>{{greeting = "hello world"}}</div>');
413+
angular.compile(template)(scope, noop);
408414
expect(template.text()).toEqual('');
409-
expect(mvc.view.text()).toEqual('hello world');
410-
expect(mvc.scope.greeting).toEqual('hello world');
415+
expect(scope.$element.text()).toEqual('hello world');
416+
expect(scope.greeting).toEqual('hello world');
411417
});
412418
});
413419
});

0 commit comments

Comments
 (0)