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

feat(ngRepeat): ngRepeat is now immune to removing or moving its elements without its corresponding comment node #6016

Closed
wants to merge 5 commits into from

Conversation

kamilkp
Copy link
Contributor

@kamilkp kamilkp commented Jan 28, 2014

This PR closes issues: #5054, #4954, #5619.

The ngRepeatDirective internally checks if one of its elements is being removed/inserted properly (with its corresponding comment element as ngRepeat does) or not. And if not (as sortable functions/directives do) it removes the comment node when needed, and then inserts it when needed and where it's supposed to. Now any sortable directive will work properly (e.g. https://github.com/mostr/angular-ui-multi-sortable or even raw jQuery (multi)sortable)

@tobio
Copy link

tobio commented Feb 4, 2014

+1 Is this likely to be included in the next Angular release?

@westj
Copy link

westj commented Feb 4, 2014

Same here. I'm not quite sure why #5619 was closed because as far as I can tell, its definitely a bug/feature of 1.2+ which is preventing me from upgrading.

@bpampuch
Copy link

bpampuch commented Feb 4, 2014

+2 ;)

@CGenie
Copy link

CGenie commented Feb 4, 2014

+1

@matsko matsko self-assigned this Feb 4, 2014
@mgmorcos
Copy link

mgmorcos commented Feb 5, 2014

+1

2 similar comments
@alboyadjian
Copy link

+1

@michaelpelletier
Copy link

+1

});
}
nodeElem.triggerHandler('$attach', args);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does jQuery emit these events? I can't find any evidence of it in the 2.x.x tree, so this feels wrong to me. I think I need to investigate the issue a bit to do a proper review.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this patch:

// in Angular.js
// Method signature:
//     jqLitePatchJQueryInsert(name)
// all jQuery methods that can insert an element into DOM
jqLitePatchJQueryInsert('append');
jqLitePatchJQueryInsert('prepend');
jqLitePatchJQueryInsert('before');
jqLitePatchJQueryInsert('after');
jqLitePatchJQueryInsert('replaceWith');
jqLitePatchJQueryInsert('wrapAll');

// in jqLite.js
function jqLitePatchJQueryInsert(name){
    var originalJqFn = jQuery.fn[name];
    originalJqFn = originalJqFn.$original || originalJqFn;
    insertPatch.$original = originalJqFn;
    jQuery.fn[name] = insertPatch;

    function insertPatch() {
      // jshint -W040
      var elementsAttached = jQuery(arguments[0]),
        originalResult = originalJqFn.apply(this, arguments);
      if(elementsAttached){
        elementsAttached.triggerHandler('$attach', elementsAttached);
      }
      return originalResult;
    }
}

It does emit these events. It is the exact same kind of jQuery function patch that alredy exists in angular.js for jQuery remove, empty and html functions. It's called jqLitePatchJQueryRemove

@matsko matsko assigned caitp and unassigned matsko Feb 22, 2014
jQuery.fn[name] = insertPatch;

function insertPatch() {
// jshint -W040
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What error does this silence?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then it's better to just do:

/* jshint validthis: true */

at the beginning of the function. jsHint comment directives are scoped, no need to rely on warning numbers that are cryptic & subject to change.

@kamilkp
Copy link
Contributor Author

kamilkp commented Feb 24, 2014

I updated the PR taking into consideration @mzgol 's remarks about jQuery append and remove signarutes

@mgol
Copy link
Member

mgol commented Feb 26, 2014

@kamilkp I had some other comments, at least one hasn't been taken into account yet. Just reminding. :)

@mgol
Copy link
Member

mgol commented Feb 26, 2014

BTW, we're monkey-patching jQuery more & more here; I feel that such modifications create the need to run the full jQuery test suite after applying those modifications to make sure nothing broke. Currently it would be extremely hard but jQuery plans to switch to Karma soon so maybe the test suite could be included.

That's a little OT for this particular pull request, though, just something to keep in mind.

@kamilkp
Copy link
Contributor Author

kamilkp commented Feb 27, 2014

@kamilkp I had some other comments, at least one hasn't been taken into account yet. Just reminding. :)

What exactly do you mean? I only didn't take into account the jshint suggestion. And that's because in angular sources silencing jshint is written the way I wrote it. I don't argue which way is better though, might as well be yours.

@kamilkp
Copy link
Contributor Author

kamilkp commented Mar 4, 2014

@caitp i just wanted to ask if it's likely that this PR will ever be merged ('couse it's been a month already) or if thats just the amount of time you guys need to review a PR?

@caitp
Copy link
Contributor

caitp commented Mar 4, 2014

I can't recall why I'm assigned to this one, but I really don't want to merge a patch that monkey-patches jQuery even more than is already happening.

@kamilkp
Copy link
Contributor Author

kamilkp commented Mar 4, 2014

I use the monkey-patch that already exists (for removes) and wrote another for inserts in the exact same way. I don't see why would it make matters with jQuery any worse (apart from the fact that everything works)

@Substr
Copy link

Substr commented Apr 22, 2014

@kamilkp @caitp Could this issue be progressed somehow? I like many others are waiting for this to be merged and are having to use a custom branch of angular until it is. Thanks.

@kamilkp
Copy link
Contributor Author

kamilkp commented Apr 22, 2014

I would love to see it progress somehow. And the build error after my last commit in this PR is not unserstandalble to me. Can anyone point me into the right direction to help me understand what caused this error?

@mgol
Copy link
Member

mgol commented Apr 22, 2014

@kamilkp It seems the error is not related to your patch so amending the commit and then pushing with --force should re-run the tests.

Anyway, I agree with @caitp that it's risky to monkey-patch jQuery more. If we ever want to do it, I think it's crucial to test jQuery modified by Angular if it passes all jQuery unit tests. Until that happens (hopefully soon), I think risks outweigh the gains.

@mgol
Copy link
Member

mgol commented May 12, 2014

FYI, in a recent commit: d71dbb1 I did sth going in the opposite direction, i.e. we know no longer patch all these individual jQuery methods and instead just hook to jQuery.cleanData. For reasons of such a change read the commit message.

This PR would need to bring some of those patches back and neither me, nor @caitp, nor @IgorMinar (we talked about it recently) want to go into that direction. The risk of breaking sth is just too high, especially that we need to work with multiple jQuery versions and we currently don't even test if our patches don't break the jQuery test suite.

@IgorMinar
Copy link
Contributor

+1 for what @mzgol said. we used to patch jquery because we were not aware of a better solution to ensuring proper memory cleanup. With d71dbb1 we no longer need to monkey patch many jquery methods and hope for the best.

As Tobias mentioned in #5619 (comment) having something other library modify DOM produced and controlled by Angular will always result in weird issues and can't be made work reliably.

We appreciate the PR, but it's aligned with the direction we want to go, so I'm going to close it.

@IgorMinar IgorMinar closed this May 12, 2014
@kamilkp
Copy link
Contributor Author

kamilkp commented Jun 10, 2014

I have written a module to obtain a sortable behaviour with no jQuery nor jQueryUI needed whatsoever. And it also doesn't break the ngRepeat inner logic which was the reason for submitting this PR. The module can be found here and a demo here

@mgol
Copy link
Member

mgol commented Jun 10, 2014

Note that jQuery UI has very good accessibility support so it's not that
it's easy to quickly replace all it does under the hood; a lot of effort
went into that. Unfortunately it's not compatible with the Angular
paradigm, though so replacement is needed for Angular projects.

@kamilkp
Copy link
Contributor Author

kamilkp commented Jun 10, 2014

I am aware of that.
My sortable module is still in very early stage, and i plan to add all of the options that jQuery sortable provides. So far i only support setting containment and handles but i will also add custom helpers and other features. All in a handy declarative way, the way that angular is designed to be used.

@mgol
Copy link
Member

mgol commented Jun 10, 2014

Sure, I didn't want to discourage you, I just wanted to warn people reading
it that it's far from being a complete replacement. :)

Michał Gołębiowski

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

Successfully merging this pull request may close these issues.