diff options
| author | Misko Hevery | 2012-02-09 14:39:44 -0800 | 
|---|---|---|
| committer | Misko Hevery | 2012-02-21 22:46:01 -0800 | 
| commit | 7bd69d0f5b1dd9aa04ac19393991566785ec81c2 (patch) | |
| tree | bfca161f26bc72bd740ed9e5c399e6c5e8f2d96f | |
| parent | 3773323e464bf45eed8cc70082ab369507d4e14d (diff) | |
| download | angular.js-7bd69d0f5b1dd9aa04ac19393991566785ec81c2.tar.bz2 | |
chore(ng:switch): rewritten with transclusion API
BREAKING CHANGE: the change event fires on scope of switch not on scope of case.
| -rw-r--r-- | src/AngularPublic.js | 2 | ||||
| -rw-r--r-- | src/widgets.js | 104 | ||||
| -rw-r--r-- | test/widgetsSpec.js | 9 | 
3 files changed, 55 insertions, 60 deletions
| diff --git a/src/AngularPublic.js b/src/AngularPublic.js index ac7d4243..a317d4dd 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -93,6 +93,8 @@ function publishExternalAPI(angular){              ngSubmit: ngSubmitDirective,              ngStyle: ngStyleDirective,              ngSwitch: ngSwitchDirective, +            ngSwitchWhen: ngSwitchWhenDirective, +            ngSwitchDefault: ngSwitchDefaultDirective,              ngOptions: ngOptionsDirective,              ngView: ngViewDirective,              ngTransclude: ngTranscludeDirective diff --git a/src/widgets.js b/src/widgets.js index a465bc88..760a7256 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -161,75 +161,67 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'        </doc:source>        <doc:scenario>          it('should start in settings', function() { -         expect(element('.doc-example-live ng\\:switch').text()).toEqual('Settings Div'); +         expect(element('.doc-example-live ng\\:switch').text()).toMatch(/Settings Div/);          });          it('should change to home', function() {           select('selection').option('home'); -         expect(element('.doc-example-live ng\\:switch').text()).toEqual('Home Span'); +         expect(element('.doc-example-live ng\\:switch').text()).toMatch(/Home Span/);          });          it('should select deafault', function() {           select('selection').option('other'); -         expect(element('.doc-example-live ng\\:switch').text()).toEqual('default'); +         expect(element('.doc-example-live ng\\:switch').text()).toMatch(/default/);          });        </doc:scenario>      </doc:example>   */ -var ngSwitchDirective = ['$compile', function($compile){ -  return { -    compile: function(element, attr) { -      var watchExpr = attr.on, -        changeExpr = attr.change, -        casesTemplate = {}, -        defaultCaseTemplate, -        children = element.children(), -        length = children.length, -        child, -        when; - -      if (!watchExpr) throw new Error("Missing 'on' attribute."); -      while(length--) { -        child = jqLite(children[length]); -        // this needs to be here for IE -        child.remove(); -        // TODO(misko): this attr reading is not normilized -        when = child.attr('ng:switch-when'); -        if (isString(when)) { -          casesTemplate[when] = $compile(child); -          // TODO(misko): this attr reading is not normilized -        } else if (isString(child.attr('ng:switch-default'))) { -          defaultCaseTemplate = $compile(child); +var NG_SWITCH = 'ng-switch'; +var ngSwitchDirective = valueFn({ +  compile: function(element, attr) { +    var watchExpr = attr.ngSwitch || attr.on, +        cases = {}; + +    element.data(NG_SWITCH, cases); +    return function(scope, element){ +      var selectedTransclude, +          selectedElement; + +      scope.$watch(watchExpr, function(value) { +        if (selectedElement) { +          selectedElement.remove(); +          selectedElement = null;          } -      } -      children = null; // release memory; -      element.html(''); - -      return function(scope, element, attr){ -        var changeCounter = 0; -        var childScope; -        var selectedTemplate; +        if ((selectedTransclude = cases['!' + value] || cases['?'])) { +          scope.$eval(attr.change); +          selectedTransclude(scope.$new(), function(caseElement, scope) { +            selectedElement = caseElement; +            element.append(caseElement); +            element.bind('$destroy', bind(scope, scope.$destroy)); +          }); +        } +      }); +    }; +  } +}); -        scope.$watch(watchExpr, function(value) { -          element.html(''); -          if ((selectedTemplate = casesTemplate[value] || defaultCaseTemplate)) { -            changeCounter++; -            if (childScope) childScope.$destroy(); -            childScope = scope.$new(); -            childScope.$eval(changeExpr); -          } -        }); +var ngSwitchWhenDirective = valueFn({ +  transclude: 'element', +  priority: 500, +  compile: function(element, attrs, transclude) { +    var cases = element.inheritedData(NG_SWITCH); +    assertArg(cases); +    cases['!' + attrs.ngSwitchWhen] = transclude; +  } +}); -        scope.$watch(function() {return changeCounter;}, function() { -          element.html(''); -          if (selectedTemplate) { -            selectedTemplate(childScope, function(caseElement) { -              element.append(caseElement); -            }); -          } -        }); -      }; -    } -  }; -}]; +var ngSwitchDefaultDirective = valueFn({ +  transclude: 'element', +  priority: 500, +  compile: function(element, attrs, transclude) { +    var cases = element.inheritedData(NG_SWITCH); +    assertArg(cases); +    cases['?'] = transclude; +  } +});  /* diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js index 4cad31ad..65ab59e5 100644 --- a/test/widgetsSpec.js +++ b/test/widgetsSpec.js @@ -10,12 +10,13 @@ describe('widget', function() {    describe('ng:switch', function() {      it('should switch on value change', inject(function($rootScope, $compile) {        element = $compile( -        '<ng:switch on="select">' + +        '<div ng-switch="select">' +            '<div ng:switch-when="1">first:{{name}}</div>' +            '<div ng:switch-when="2">second:{{name}}</div>' +            '<div ng:switch-when="true">true:{{name}}</div>' + -        '</ng:switch>')($rootScope); -      expect(element.html()).toEqual(''); +        '</div>')($rootScope); +      expect(element.html()).toEqual( +          '<!-- ngSwitchWhen: 1 --><!-- ngSwitchWhen: 2 --><!-- ngSwitchWhen: true -->');        $rootScope.select = 1;        $rootScope.$apply();        expect(element.text()).toEqual('first:'); @@ -55,7 +56,7 @@ describe('widget', function() {          '</ng:switch>')($rootScope);        $rootScope.url = 'a';        $rootScope.$apply(); -      expect($rootScope.name).toEqual(undefined); +      expect($rootScope.name).toEqual('works');        expect(element.text()).toEqual('works');      }));    }); | 
