Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

templateURL in directive breaks interpolation in $observe #1941

Closed
joshdmiller opened this issue Feb 2, 2013 · 21 comments
Closed

templateURL in directive breaks interpolation in $observe #1941

joshdmiller opened this issue Feb 2, 2013 · 21 comments

Comments

@joshdmiller
Copy link

When using the templateUrl property, attrs.$observe will no longer interpolate values. See the following example (also in this plunker):

.directive( 'testDir', [ function () {
  return {
    restrict: 'A',
    scope: true,
    templateUrl: 'template.html',
    //template: "<span>{{testAttr}}</span>",
    link: function( scope, element, attrs ) {
      attrs.$observe( 'testDir', function ( val ) {
        console.log("attr changed to", val);
        scope.testAttr = val;
      });
    }
  };
}]);

This will work if either (a) template is used instead of templateUrl; or (b) an isolate scope with an '@' binding is used instead.

I cannot explain this behavior, so I am opening this issue. Thanks!

@IgorMinar
Copy link
Contributor

this does look like a weird bug.

I debugged it a bit and the reason why this is happening is that the testDir directive is observing different instane of Attributes than then one that the interpolation is registered with. So somehow we are creating two instances of the Attributes object of this single element. I don't yet know why that's the case, but this is the issue that needs to be fixed.

@IgorMinar
Copy link
Contributor

ok, here is the culprit:

afterTemplateNodeLinkFn = applyDirectivesToNode(directives, $compileNode, tAttrs, childTranscludeFn);

we should be calling applyDirectiveToNode with compileNode and not $compileNode.

does anybody want to take it from here and write a test for this and send a PR?

@iknite
Copy link

iknite commented Feb 4, 2013

Hi, I can't make the this test catch the bug, It passed but I think it's about letting the $rootScope.$apply() do the compilation.

Any directions are gladly appreciated :)

it('should support $observe inside link function on directive object', function(){
  module(function() {
    directive('testLink', valueFn({
      link: function(scope, element, attrs) {
        attrs.$observe( 'testLink', function ( val ) {
          scope.testAttr = val;
        });
      }
    }));
  });
  inject(function($compile, $rootScope) {
    element = $compile('<div test-link="{{1+2}}">{{testAttr}}</div>')($rootScope);
    $rootScope.$apply(); //what's the right way to process the directive?
    expect(element.text()).toBe('3');
  });
});

@IgorMinar
Copy link
Contributor

@iknite you have to use templateUrl in your testLink directive

@IgorMinar
Copy link
Contributor

templateUrl: test-link.html

...

inject(function($compile, $rootScope, $templateCache) {
  $templateCache('test-link.html', '{{testAttr}}');
  element = $compile('<div test-link="{{1+2}}"></div>')($rootScope);
  ...

@IgorMinar IgorMinar reopened this Feb 4, 2013
IgorMinar pushed a commit to IgorMinar/angular.js that referenced this issue Feb 7, 2013
Directives was observing different instances of Attributes than the one
that interpolation was registered with because we failed to realize
that the compile node and link node were the same (one of them
was a wrapper rather than raw node)

Closes angular#1941
IgorMinar pushed a commit that referenced this issue Feb 7, 2013
Directives was observing different instances of Attributes than the one
that interpolation was registered with because we failed to realize
that the compile node and link node were the same (one of them
was a wrapper rather than raw node)

Closes #1941
@jingman
Copy link

jingman commented Feb 23, 2013

This issue comes back (plunker) when you add replace: true to the directive.

@IgorMinar IgorMinar reopened this Feb 23, 2013
@IgorMinar
Copy link
Contributor

Hmm.. OK, we'll investigate.

@XavierWRS
Copy link

The bug also occus when templateUrl is used with ng-repeat directive (even when replace:true is NOT used)

In the plunker, add an ng-repeat like ng-repeat="task in tasks" div test-dir ...
and in the controller, add $scope.tasks = ['1','2','3];

You'll see it will break the interpolation in $observe

@zllak
Copy link

zllak commented Mar 29, 2013

Any news on this issue? This got me pretty stuck, and no simple workaround seems to be possible :)

@XavierWRS
Copy link

So far, I don't use templateUrl but template. You have to write your HTML template within the javascript file (not very clean) but it works...

@filso
Copy link

filso commented Apr 24, 2013

This still doesn't work with templateUrl. I inject $interpolate, and do that: scope.arg = $interpolate(attrs.arg)(scope);

@jingman
Copy link

jingman commented Apr 24, 2013

Thanks for the tip @fsobczak, I'm bummed we still have to hack this.

@Falx
Copy link

Falx commented Jul 17, 2013

Still nothing for this problem? I can still not use templateUrls because of this..

@jingman
Copy link

jingman commented Jul 17, 2013

I drop back into the Plunkr every few weeks to see if it works with the latest version (stable or dev). No luck yet. :(

slundberg pushed a commit to slundberg/angular.js that referenced this issue Jul 31, 2013
…rve when using a templateUrl for a directive. http://plnkr.co/edit/xJNt918gEpuXR026VuZB?p=preview illustrates the issue that was fixed
@gustavo80br
Copy link

I'm using replace:true, templateUrl in a directive that is inside ng-repeat. Having this issue. AlgularJS 1.0.7. I'm using $parse inside the directive to workaround this.

@karl
Copy link

karl commented Aug 21, 2013

Any news on a fix for this?

If the fix is not forthcoming is there a workaround for the problem that allows us to keep using templateUrl? If so would someone be able to explain it?

@karl
Copy link

karl commented Aug 21, 2013

OK, I managed to work around the issue myself by interpolating the attributes when I needed them.

I've updated the Plunker to show the fix:

http://plnkr.co/edit/5kDzORMCCMefecC1L5xy?p=preview

@SurajPatnaik
Copy link

When this issue is gonna fixed?

@ghost
Copy link

ghost commented Sep 7, 2013

Code Bounty

@btford
Copy link
Contributor

btford commented Oct 2, 2013

This is currently working in master. Here's a plunker with a recent build from our CI server: http://plnkr.co/edit/hlRvhR8uzZF6P02iEBYa?p=preview

If I'm incorrect and the issue still persists, I'd be happy to re-open this.

@btford btford closed this as completed Oct 2, 2013
@jingman
Copy link

jingman commented Oct 2, 2013

Sweet! Thanks for the update @btford!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.