Skip to content

Directive doesn't seem to work inside ng-repeat #24

Closed
rlodge opened this Issue Nov 9, 2013 · 17 comments
@rlodge
rlodge commented Nov 9, 2013

I'm trying to use the directive on a page where I have a variable number of segments of code I want edited separately, so I'm trying to use it inside ng-repeat.

I've created a plunk at http://plnkr.co/edit/bvrAFV7LcINIYuuaYkw3?p=preview based on one of the demos. This uses pretty old versions of the directive and CM itself, I think, but I've tried newer versions and it doesn't seem to help.

Am I doing something wrong? Is it simply unable to work in this way? Or is there a bug somewhere?

Thanks.

Ross

@hitenv
hitenv commented Nov 20, 2013

Im having the same problem, any ideas on how i can resolve this? i see that ace editor is working fine, but not code mirror. I want to use code mirror because of the bi-directional support.

thanks in advance

hiten

@selckin
selckin commented Nov 21, 2013

Hit the same problem

Believe it's because the codemirror element is not attached to the dom ? and therefor it can't calculate some sizes correctly, therefore the style is messed and it shows empty

@selckin
selckin commented Nov 21, 2013

And indeed just moving the code mirror init inside postLink mostly works, but some attributes seem to go missing then (like CodeMirror is missing from 'class'), i'm too new to angular to know whats going on there

@selckin
selckin commented Nov 21, 2013

This makes it work, but not sure how to properly fix it

@@ -21,8 +21,11 @@ angular.module('ui.codemirror', [])
         // - the initial content of the editor.
         //   see http://codemirror.net/doc/manual.html#api_constructor
         var value = tElement.text();
+        return  function postLink(scope, iElement, iAttrs, ngModel) {
+
             var codeMirror = new CodeMirror(function (cm_el) {

+                /*
                 angular.forEach(tElement.prop("attributes"), function (a) {
                     if (a.name === "ui-codemirror") {
                         cm_el.setAttribute("ui-codemirror-opts", a.textContent);
@@ -35,12 +38,11 @@ angular.module('ui.codemirror', [])
                 if (tElement.parent().length <= 0) {
                     tElement.wrap("<div>");
                 }
+                */

-          tElement.replaceWith(cm_el);
+                iElement.append(cm_el);
             }, {value: value});

-        return  function postLink(scope, iElement, iAttrs, ngModel) {
-
             var options, opts, onChange;

           options = uiCodemirrorConfig.codemirror || {};
@chrisfoster78

It appears to break with angular versions 1.2+ of angular. 1.1.5 seems to work okay for me.

@rlodge
rlodge commented Nov 21, 2013

The plunk I linked in my original comment used 1.0.7; I updated it to 1.1.5 and still see the problem. I've tried 1.2 and it also doesn't work.

@klwemu
klwemu commented Nov 21, 2013

Same problem. The old version of the directive works (with Angular 1.5 + 1.2) , the new not.

@HarishAtGitHub

I am having a similar problem ...ui-codemirror does not seem to work inside another custom directive ..
it just shows a space without line numbers and even not editable

@douglasduteil
AngularUI member

The solution of @selckin seems to work pretty well http://plnkr.co/aL1Xqk
I'm running tests trying to see if it breaks

@s3thi
s3thi commented Feb 3, 2014

FWIW, I'm using @selckin's fix and it works well in the browser, but I keep running into "$digest already in progress" errors when I run my unit tests. Not sure whether the issue is my code or the directive. Still investigating.

@mik01aj
mik01aj commented Feb 10, 2014

I tried @selckin's fix, but it didn't work for me.

I have 2 textareas with ui-codemirror directive, one within a tabset from Angular Bootstrap, and one outside. Now, when I use the original ui-codemirror from commit 18317b7c, only the outside one works. After applying the patch none of them works (and there is no error on the console). :(

@mcampa
mcampa commented Mar 10, 2014

@mik01aj I had the same problem. Try using the ui-refresh.

Something like this:

<div ui-codemirror="tab.options" ng-model="tab.content" ui-refresh="tab.refresh"></div>
        $scope.tabChange = function(tab) 
        {
            // your code

            tab.refresh += 1;
        }
@brunosmartin

The code from douglasduteil worked for me with ng-repeat.

@blacklab
blacklab commented Apr 3, 2014

I had the same issue with ng-switch. The fix worked for me. However, embedding text in the ui-codemirror tag does not work anymore:

<div ui-codemirror="loadedCode">Some Code here</div>

Will show "Some Code here" even if loadedCode is set.

@brunosmartin

The work around I did was to use textarea tag instead of div with an ng-model.

@laurelnaiad

For what it's worth, the patch doesn't work for me in the following case;

<custDctv1>   <!-- my own very simple transcluder -->
  <custDctv2></custDctv2>   <!-- this one has ui-codemirror in its template -->
</custDctv1>

If I take out the transcluding directive, it works fine. This seems consistent with people struggling with ng-repeat, as well as previous times I've given up trying to get ui-codemirror to work with ui-bootstrap tabs. I have found none of the workarounds to help. It did encourage me to simplify my directives and get rid of the the transclusion, though 😄. Not sure what I'll do if my requirements bring back tabs 😦.

@douglasduteil
AngularUI member

Working now boys (v0.1.2)
I defiantly took too much my time for this... sorry
http://embed.plnkr.co/PyQ5wmMm5PsrLXeReuuq/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.