Вы можете использовать * ngIf
Шаблон:
<div *ngIf="display">Test Data</div>
<input type="button" value="click" (click)="update"/>
Компонент:
display = true;
update(){
this.display = !this.display;
}
Assume that a class has 5 known properties - date, time, subject, outline, location. When I look at my schedule, I'm most interested in the most recent (ie current/accurate) version of these properties. It would also be useful for me to know what, if anything, has changed. (As a side note, if the date, time or location changed, I'd also expect to get an email/sms advising me in case I don't check for an updated schedule :-))
I would suggest that the 'diff' is performed at the time the schedule is amended. So, when version 2 of the class is created, record which values have changed, and store this in two 'changelog' fields on the version 2 object (there must already be one parent table that sits atop all your tables - use that one!). One changelog field is 'human readable text' eg 'Date changed from Mon 1 May to Tues 2 May, Time changed from 10:00am to 10:30am'. The second changelog field is a delimted list of changed fields eg 'date,time' To do this, before saving you would loop over the values submitted by the user, compare to current database values, and concatenate 2 strings, one human readable, one a list of field names. Then, update the data and set your concatenated strings as the 'changelog' values.
When displaying the schedule load the current version by default. Loop through the fields in the changelog field list, and annotate the display to show that the value has changed (a * or a highlight, etc). Then, in a separate panel display the human readable change log.
If a schedule is amended more than once, you would probably want to combine the changelogs between version 1 & 2, and 2 & 3. Say in version 3 only the course outline changed - if that was the only changelog you had when displaying the schedule, the change to date and time wouldn't be displayed.
Note that this denormalised approach won't be great for analysis - eg working out which specific location always has classes changed out of it - but you could extend it using an E-A-V model to store the change log.
Просто идея, но стоит ли вам преобразовать две сравниваемые версии объекта в какой-то текстовый формат, а затем сравнить эти текстовые объекты с помощью существующей программы сравнения, например diff
например? Есть много хороших программ сравнения, которые могут предложить хорошее визуальное представление и т. Д.
Так, например,
Текстовая версия Объекта 1:
first_name: Harry
last_name: Lime
address: Wien
version: 0.1
Текстовая версия Объекта 2:
first_name: Harry
last_name: Lime
address: Vienna
version: 0.2
Различие было бы чем-то например:
3,4c3,4
< address: Wien
< version: 0.1
---
> address: Vienna
> version: 0.2
Я изучал MysQL Diffing несколько раз. К сожалению, действительно хороших решений нет.
Я пробовал использовать mysqldiff (www.mysqldiff.org). mysqldiff - это инструмент, написанный на PHP, который может различать схемы mysql. К сожалению, в большинстве случаев это не очень хорошо.
MySQL Workbench, собственная SQL IDE MySQL предоставляет возможность сгенерировать сценарий изменения, и я предполагаю, что он делает это, выполняя какую-то внутреннюю операцию сравнения.
Aqua Data Studio - еще один инструмент, способный сравнивать схемы и выводить разницу между ними. Хотя ADS diff довольно хорош, он не предоставляет инструмента для создания сценария изменения.
Если бы я писал свой собственный, я бы, наверное, написал код, способный сравнивать структуру двух таблиц. Такой код можно настроить так, чтобы он был высокочувствительным (Ig, если порядок столбцов отличается от версии к следующей, это разница) или более умеренно чувствительным (например, порядок столбцов не является серьезной проблемой, типы данных и длина важны, как индексы и ограничения).
Хранение, я не уверен. Я бы посмотрел, как система управления версиями, такая как Mercurial, хранит свою информацию о различиях для ревизий, и использовал ее для разработки метода, подходящего для БД.
Наконец, для визуального вывода я рекомендую вам взглянуть на сравнение Aqua Data Stduio функция (вы можете использовать пробную версию, чтобы проверить это ...). Его вывод diff довольно хорош.
типы данных и длина важны, как индексы и ограничения).Хранение, я не уверен. Я бы посмотрел, как система управления версиями, такая как Mercurial, хранит свою информацию о различиях для ревизий, и использовал ее для разработки метода, подходящего для БД.
Наконец, для визуального вывода я рекомендую вам взглянуть на сравнение Aqua Data Stduio функция (вы можете использовать пробную версию, чтобы проверить это ...). Его вывод diff довольно хорош.
типы данных и длина важны, как индексы и ограничения).Хранение, я не уверен. Я бы посмотрел, как система управления версиями, такая как Mercurial, хранит свою информацию о различиях для ревизий, и использовал ее для разработки метода, подходящего для БД.
Наконец, для визуального вывода я рекомендую вам взглянуть на сравнение Aqua Data Stduio функция (вы можете использовать пробную версию, чтобы проверить это ...). Его вывод diff довольно хорош.
Было бы хорошо провести сравнение на уровне базы данных, если бы вас интересовали изменения в базе данных. Это имеет наибольший смысл, если вы пытаетесь спроектировать уровень общих функций поверх самой базы данных.
Выполнение сравнения на уровне объекта было бы хорошо, если вы заботитесь об изменениях в данных. Например, если данные были входными данными для программы, и вы хотели посмотреть на изменения во входных данных, чтобы убедиться, что изменения в выходных данных были правильными.
Похоже, ваш вариант использования не соответствует ни одному из этих вариантов. Вы, кажется, заботитесь о результатах и хотите отличий с этой точки зрения. Если это так, я бы сделал различия в выходном отчете (или его чисто текстовой версии), а не в базовых данных. Вы можете сделать это с помощью любого стандартного инструмента сравнения. Чтобы упростить задачу конечным пользователям, вы можете проанализировать результаты сравнения и отобразить их в формате HTML. Здесь есть много вариантов: рядом с цветовой кодировкой для обозначения изменений, один документ с разметкой для изменений (например, красный зачеркнутый для удаления и зеленый для добавления), возможно, просто выделите области, которые изменились, и используйте выноски, чтобы показать предыдущие / текущие значения по запросу.
Я думал о сравнении баз данных, но никогда не пытался реализовать это. Как вы заметили, любые такие попытки тесно связаны со схемой.
Я провел сравнения на уровне объектов. Общий алгоритм был следующим:
В моем случае алгоритмы сравнения были написаны вручную, чтобы соответствовать атрибутам объекта. Это дало мне контроль над тем, какие атрибуты сравнивать и как. В некоторых случаях можно использовать универсальный компаратор, но он будет зависеть от ситуации и, по крайней мере частично, от языка реализации.
алгоритмы сравнения были написаны вручную, чтобы соответствовать атрибутам объекта. Это дало мне контроль над тем, какие атрибуты сравнивать и как. В некоторых случаях можно использовать универсальный компаратор, но он будет зависеть от ситуации и, по крайней мере частично, от языка реализации. алгоритмы сравнения были написаны вручную, чтобы соответствовать атрибутам объекта. Это дало мне контроль над тем, какие атрибуты сравнивать и как. В некоторых случаях можно использовать универсальный компаратор, но он будет зависеть от ситуации и, по крайней мере частично, от языка реализации.Я бы подумал о каком-то общем текстовом представлении объектов и позволил бы текстам сравнить с существующим инструментом сравнения, таким как WinMerge.
Я не вижу необходимости изобретать различия самостоятельно, поскольку там я уже могу использовать множество хороших инструментов.
Мой сценарий базы данных приложения сравнивает иерархические данные (схемы базы данных) в хранимой процедуре, которая, конечно же, должна сравнивать каждое поле / свойство каждого объекта с его аналогом. Думаю, вы не обойдете этот шаг (если у вас нет общей модели описания объекта)
Что касается части вашего вопроса, связанной с пользовательским интерфейсом, посмотрите скриншоты, чтобы просмотреть и выбрать различия.
На самом деле это не ответ на заданный вами вопрос, а скорее попытка переосмыслить проблему. Не могли бы вы изменить свою базу данных и объектную модель для хранения совокупного корня и ряда дельт? То есть моделируйте и сохраняйте RevisionSets, которые являются коллекциями Revision; Ревизия - это свойство сущности, связанное со значением. В некотором смысле это встраивает структуру ревизий в вашу архитектуру, и другие плакаты предлагают вам закрепить то, что у вас уже есть, с помощью «журналов».
Отображать агрегированные данные из дельт тривиально, а еще проще - отображать дельты как историю изменений. Тот факт, что вы используете многофункциональный клиент с памятью состояния и локальной памятью, делает это еще более убедительным. Вы можете легко отобразить «все изменения с даты xxxx»
Я теряю то, что предложил Гарри Лайм: выведите свои свойства в текстовый формат, а затем хешируйте результаты. Таким образом, вы можете сравнивать значения хеш-функции и легко отмечать измененные данные. Таким образом, вы получите лучшее из обоих миров: вы можете визуально видеть различия, но программно определять различия. С has у вас будет хороший источник индекса, если вы захотите сохранить и извлечь дельты.
В вашей ситуации в PostgreSQL я использовал таблицы различий со схемой:
history_columns (
column_id smallint primary key,
column_name text not null,
table_name text not null,
unique (table_name, column_name)
);
create temporary sequence column_id_seq;
insert into history_columns
select nextval('column_id_seq'), column_name, table_name
from information_schema.columns
where
table_name in ('table1','table2','table3')
and table_schema=current_schema() and table_catalog=current_database();
create table history (
column_id smallint not null references history_columns,
id int not null,
change_time timestamp with time zone not null
constraint change_time_full_second -- only one change allowed per second
check (date_trunc('second',change_time)=change_time),
primary key (column_id,id,change_time),
value text
);
А в таблицах я использовал триггер вроде этого:
create or replace function save_history() returns trigger as
$$
if (tg_op = 'DELETE') then
insert into historia values (
find_column_id('id',tg_relname), OLD.id,
date_trunc('second',current_timestamp),
OLD.id );
[for each column_name] {
if (char_length(OLD.column_name)>0) then
insert into history values (
find_column_id(column_name,tg_relname), OLD.id,
OLD.change_time, OLD.column_name
)
}
elsif (tg_op = 'UPDATE') then
[for each column_name] {
if (OLD.column_name is distinct from NEW.column_name) then
insert into history values (
find_column_id(column_name,tg_relname), OLD.id,
OLD.change_time, OLD.column_name
);
end if;
}
end if;
$$ language plpgsql volatile;
create trigger save_history_table1
before update or delete on table1
for each row execute procedure save_history();
Учитывая, что вы хотите создать пользовательский интерфейс для этого и вам нужно указать, где находятся различия, мне кажется, что вы можете выбрать индивидуальный вариант или создать общий компаратор объектов - последнее зависит от язык, который вы используете.
Для пользовательского метода вам необходимо создать класс, который принимает два экземпляра классов для сравнения. Затем он возвращает различия;
public class Person
{
public string name;
}
public class PersonComparer
{
public PersonComparer(Person old, Person new)
{
....
}
public bool NameIsDifferent() { return old.Name != new.Name; }
public string NameDifferentText() { return NameIsDifferent() ? "Name changed from " + old.Name + " to " + new.Name : ""; }
}
Таким образом, вы можете использовать объект NameComparer для создания вашего графического интерфейса.
Gereric подход будет почти таким же, только вы обобщаете вызовы и используете проверку объекта (вызов getObjectProperty ниже) для найти различия;
public class ObjectComparer()
{
public ObjectComparer(object old, object new)
{
...
}
public bool PropertyIsDifferent(string propertyName) { return getObjectProperty(old, propertyName) != getObjectProperty(new, propertyName) };
public string PropertyDifferentText(string propertyName) { return PropertyIsDifferent(propertyName) ? propertyName + " " + changed from " + getObjectProperty(old, propertyName) + " to " + getObjectProperty(new, propertyName): ""; }
}
}
Я бы выбрал второй вариант, так как он позволяет легко изменять графический интерфейс пользователя по мере необходимости. Графический интерфейс Я бы попробовал «пожелтеть» различия, чтобы их было легче увидеть, но это зависит от того, как вы хотите показать различия.
Example with Oracle.