Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(table): update implicit when using trackby #7893

Merged
merged 3 commits into from
Oct 27, 2017

Conversation

andrewseguin
Copy link
Contributor

The table should make sure that if it wants to re-use a row, then it's implicit data should be accurate. It's possible that a row's data is entirely changed but the row was re-used due to a loose trackBy.

Fixes #7877

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Oct 18, 2017
@andrewseguin andrewseguin added the P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful label Oct 20, 2017
@@ -68,6 +68,14 @@ export const CDK_TABLE_TEMPLATE = `
<ng-container headerRowPlaceholder></ng-container>
<ng-container rowPlaceholder></ng-container>`;

/** Class used to conveniently type the embedded view ref for rows with a context. */
abstract class RowViewRef<T> extends EmbeddedViewRef<CdkCellOutletRowContext<T>> { }
Copy link
Member

Choose a reason for hiding this comment

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

Should this be @docs-private?

abstract class RowViewRef<T> extends EmbeddedViewRef<CdkCellOutletRowContext<T>> { }

/** Tuple used to pair together an iterable differ change record with the view it affects. */
class RowRecordViewTuple<T> {
Copy link
Member

Choose a reason for hiding this comment

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

@docs-private?


/** Tuple used to pair together an iterable differ change record with the view it affects. */
class RowRecordViewTuple<T> {
constructor(public record: IterableChangeRecord<T>, public view: RowViewRef<T>) {}
Copy link
Member

Choose a reason for hiding this comment

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

Should record and view be public, documented properties?

Copy link
Member

Choose a reason for hiding this comment

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

Also neither seem to be the most descriptive names

private _renderRowChanges() {
const changes = this._dataDiffer.diff(this._data);
if (!changes) { return; }

const insertOrMovedRowTuples: RowRecordViewTuple<T>[] = [];
Copy link
Member

Choose a reason for hiding this comment

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

Add comment that explains why you keep track of the inserted or moved tuples?


// Update rows that did not get added/removed/moved but may have had their identity changed,
// e.g. if trackBy matched data on the property 'id' but the property 'name' was changed.
changes.forEachIdentityChange((record: any) => {
Copy link
Member

Choose a reason for hiding this comment

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

Why any?

}

/**
* Updates the context for each row to reflect any data changes that may have caused
* Updates the meta context for each row to reflect any data changes that may have caused
Copy link
Member

Choose a reason for hiding this comment

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

"Meta context"?

}

/** Updates the row view ref with the implicit data assigned to the row. */
private _updateRowImplicitContext(view: RowViewRef<T>, record: IterableChangeRecord<any>) {
Copy link
Member

Choose a reason for hiding this comment

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

I think the code would be easier to read without this method (just having the assignment inline). Any reason to keep it a method?

}
});

this._updateRowContext();
// Update the row's implicit context for each inserted or moved row.
Copy link
Member

Choose a reason for hiding this comment

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

"Update the $implicit property for the binding context for inserted and moved rows"

@andrewseguin
Copy link
Contributor Author

andrewseguin commented Oct 23, 2017

tl;dr: Took out logic about insertions and moves. Just updating for identity changes since it addresses the issue.


Reducing the scope of this PR - was looking at Angular's ngFor (ng_for_of.ts) to see how they addressed this issue. They updated row $implicit on insert/move and also for any identity changes. The issue was fixed with the identity change and I'm not convinced we need the former (updating on insert/move, which should be addressed already on insert).

If another issue comes in about bad $implicit on moves then we'll know where to look, but I'm not 100% convinced it's needed.

Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

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

LGTM, one syntax comment

Add the "merge-ready" label when done

// Change each item reference to show that the trackby is checking the index.
// Otherwise this would cause them all to be removed/added.
trackByComponent.dataSource.data = trackByComponent.dataSource.data
.map(item => { return {a: item.a, b: item.b, c: item.c}; });
Copy link
Member

Choose a reason for hiding this comment

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

.map(item => ({a: item.a, b: item.b, c: item.c}));

@andrewseguin andrewseguin added the action: merge The PR is ready for merge by the caretaker label Oct 24, 2017
@mmalerba mmalerba merged commit f806286 into angular:master Oct 27, 2017
@andrewseguin andrewseguin deleted the table-change-context branch November 28, 2017 20:38
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Table] Rows are not provided correct $implicit with trackBy
4 participants