Comment comparer deux modèles de classe et trouver les différences correspondantes? Voici deux modèles qui ont exactement les mêmes membres, et nous devons comparer.
Y a-t-il un algorithme dans Typescript qui effectue cela? * Une nouvelle classe de résultat devrait être créée avec des membres de classe et un indicateur booléen différent?
Vous cherchez un moyen simple dans l'algorithme Typescript. Il doit accepter n'importe quelle classe,
Remarque: certains membres de la classe contiennent une classe elle-même.
actuellement
Exemple de tableau de classe de résultat: s'il existe une méthode de stockage plus optimale, n'hésitez pas à modifier export class DifferenceClass {
ClassMember: string;
DifferentFlag: boolean
}
4 Réponses :
Pourquoi ne pas simplement créer une méthode / fonction dans votre classe qui exécute la comparaison. Vous pouvez le faire en comparant chaque propriété individuellement (en tapant tout) ou en bouclant simplement chaque clé de votre classe et en la comparant à chaque clé de l'objet transmis.
class DifferenceClass {
constructor(classMember, differenceFlag) {
this.ClassMember = classMember;
this.DifferenceFlag = differenceFlag;
}
}
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
isSame(person) {
if (person instanceof Person) {
const differences = [];
for (const key in person) {
if (this[key] !== person[key]) {
differences.push(new DifferenceClass(key, true));
}
}
return differences;
} else {
throw new Error('Object is not a Person class');
}
}
}
const p1 = new Person('John', 'Doe');
const p2 = new Person('Jane', 'Doe');
console.log('Should be empty', p1.isSame(p1));
console.log('Should have diff results', p1.isSame(p2));
console.log('should be an exception', p1.isSame(1));
Qu'en est-il des propriétés complexes?
eh bien, il doit également marquer chaque membre qui a changé, pas seulement comparer l'objet entier, voir un exemple d'objet de classe différent au bas de la question
Je recommanderais de le faire le long du chemin dans ce cas (faire chaque comparaison individuelle manuellement). Si l'une des propriétés est une classe complexe, par exemple, vous pouvez créer une méthode similaire dans cette classe cible.
J'ai une fonction qui compare deux objets et effectue une comparaison approfondie
const diff = (obj1, obj2) => Object.keys(obj1).map(key => ({ ClassMember: key, DifferentFlag: !compare(obj1[key], obj2[key]) }));
Vous pouvez l'utiliser avec
export const compare = (obj1: any, obj2: any): boolean =>
Array.isArray(obj1)
? Array.isArray(obj2) && obj1.length === obj2.length && obj1.every((item, index) => compare(item, obj2[index]))
: obj1 instanceof Date
? obj2 instanceof Date && obj1.getDate() === obj2.getDate()
: obj1 && typeof obj1 === 'object'
? obj2 && typeof obj2 === 'object' &&
Object.getOwnPropertyNames(obj1).length === Object.getOwnPropertyNames(obj2).length &&
Object.getOwnPropertyNames(obj1).every(prop => compare(obj1[prop], obj2[prop]))
: obj1 === obj2;
cool, juste essayé, avez-vous une réponse détaillée, il doit également marquer chaque membre qui a changé, pas seulement comparer l'objet entier, voir un exemple d'objet de classe différent au bas de la question
Vous pouvez utiliser la bibliothèque deep-diff :
import { diff } from 'deep-diff';
const differences = diff(location1, location2);
Il crée un bel objet de différence avec les chemins vers les différents attributs.
merci, il doit également marquer chaque membre qui a changé, pas seulement comparer l'objet entier, voir un exemple d'objet de classe différent au bas de la question
Une autre façon serait d'utiliser un tube pour ajouter une classe à votre modèle
<div [ngClass]="{ 'changed': original | changed : new : property }">
et dans votre vue, vous pouvez ajouter une classe si l'objet a changé
import { Pipe, PipeTransform } from '@angular/core';
const resolveProperty = (obj: any, property: string): any =>
property ? property.split('.').reduce((result, prop) => (result ? result[prop] : undefined), obj) : undefined;
@Pipe({
name: 'different'
})
export class DifferentPipe implements PipeTransform {
transform(obj: any, obj2: any, property: string): boolean {
return resolveProperty(obj, property) !== resolveProperty(obj2, property);
}
}
cool, il doit également marquer chaque membre qui a changé, pas seulement comparer l'objet entier, voir un exemple d'objet de classe différent au bas de la question, le titre de la question essayait de marquer chaque membre
Vous placez cette instruction ngClass sur chaque champ qui doit être mis en évidence et remplacez la valeur de la propriété par le chemin complet de la propriété, 'streetName.addressChangeReason.prop'
c'est génial, actuellement l'ancienne et la nouvelle adresse de propriété sont dans des composants différents, le composant parent injecte les modèles de classe dans les composants de la carte séparés, de sorte qu'une donnée enfant ne peut pas voir une autre donnée enfant sœur,
Au lieu de passer un objet différent, passez dans l'objet d'origine
Pouvez-vous fournir des échantillons pour les tests?
Ce n'est pas une solution prête à l'emploi, mais cette bibliothèque pourrait vous être utile: github.com/flitbit/diff