1
votes

Typographie: itérer à travers chaque membre entre deux classes et indicateur de différence angulaire

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

 saisissez la description de l'image ici

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
}


2 commentaires

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


4 Réponses :


0
votes

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));


3 commentaires

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.



0
votes

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;


1 commentaires

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



0
votes

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.


1 commentaires

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



0
votes

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);
  }
}


4 commentaires

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