diff --git a/src/Compiler.js b/src/Compiler.js
index a355444be770..e9f2fbe88a43 100644
--- a/src/Compiler.js
+++ b/src/Compiler.js
@@ -33,7 +33,15 @@ Template.prototype = {
paths = this.paths,
length = paths.length;
for (i = 0; i < length; i++) {
- children[i].link(jqLite(childNodes[paths[i]]), childScope);
+ // sometimes `element` can be modified by one of the linker functions in `this.linkFns`
+ // and childNodes may be added or removed
+ // TODO: element structure needs to be re-evaluated if new children added
+ // if the childNode still exists
+ if (childNodes[paths[i]])
+ children[i].link(jqLite(childNodes[paths[i]]), childScope);
+ else
+ // if child no longer available, delete path
+ delete paths[i];
}
},
diff --git a/src/widget/select.js b/src/widget/select.js
index 1687721cc331..66d710bc5c74 100644
--- a/src/widget/select.js
+++ b/src/widget/select.js
@@ -243,9 +243,13 @@ angularWidget('select', function(element){
// find existing special options
forEach(selectElement.children(), function(option){
- if (option.value == '')
+ if (option.value == '') {
// User is allowed to select the null.
- nullOption = {label:jqLite(option).text(), id:''};
+ // save ');
+ scope.blankTemplate = 'so blank';
+ scope.values = [{name:'A'}];
+ scope.$digest();
+
+ // check blank option is first and is compiled
+ expect(select.find('option').length == 2);
+ option = jqLite(select.find('option')[0]);
+ expect(option.val()).toBe('');
+ expect(option.text()).toBe('blank is so blank');
+
+ // change blankTemplate and $digest
+ scope.blankTemplate = 'not so blank';
+ scope.$digest();
+
+ // check blank option is first and is compiled
+ expect(select.find('option').length == 2);
+ option = jqLite(select.find('option')[0]);
+ expect(option.val()).toBe('');
+ expect(option.text()).toBe('blank is not so blank');
+ });
+
+ it('should be compiled from ng:bind-template attribute if given instead of text', function () {
+ var option;
+
+ createSingleSelect('');
+ scope.blankTemplate = 'so blank';
+ scope.values = [{name:'A'}];
+ scope.$digest();
+
+ // check blank option is first and is compiled
+ expect(select.find('option').length == 2);
+ option = jqLite(select.find('option')[0]);
+ expect(option.val()).toBe('');
+ expect(option.text()).toBe('blank is so blank');
+ });
+
+ it('should be compiled from ng:bind attribute if given', function () {
+ var option;
+
+ createSingleSelect('');
+ scope.blankTemplate = 'is blank';
+ scope.values = [{name:'A'}];
+ scope.$digest();
+
+ // check blank option is first and is compiled
+ expect(select.find('option').length == 2);
+ option = jqLite(select.find('option')[0]);
+ expect(option.val()).toBe('');
+ expect(option.text()).toBe('is blank');
+ });
+
+ it('should be rendered with the attributes preserved', function () {
+ var option;
+
+ createSingleSelect('');
+ scope.blankTemplate = 'is blank';
+ scope.$digest();
+
+ // check blank option is first and is compiled
+ option = jqLite(select.find('option')[0]);
+ expect(option.hasClass('coyote')).toBeTruthy();
+ expect(option.attr('id')).toBe('road-runner');
+ expect(option.attr('custom-attr')).toBe('custom-attr');
+ });
+
+
+ });
describe('on change', function() {
it('should update model on change', function() {