Обработчик событий, не уволенный за динамично созданные средства управления

Вы не можете изменить любой существующий коммит. Но вы можете остановить , используя существующие коммиты.

Поскольку коммиты сохраняют полное состояние всего (ну, в общем, все зафиксированные), вы также можете «вернуться назад во времени», проверив старый коммит.

Если вы присваиваете каждому коммиту уникальный идентификатор и выводите их в последовательности, вы получаете что-то вроде этого:

A <-B <-C <-D   <--master

То есть последний коммит, D, запоминает идентификатор его предыдущий - или родитель - коммит C. Между тем C помнит своего родителя, B, который помнит своего родителя A. (Если A является самым первым коммитом в репозитории, у него нет родителя, поскольку он не может иметь его. В противном случае A запоминает, какой коммит был до A.)

Способ Git находит это то, что имя master записывает идентификатор хэша последнего коммита . Так как это было D, master находит D. Поскольку D записывает идентификатор C, сам D находит C, который находит B и т. Д.

Итак, учитывая все это, предположим, что вы:

  1. Проверьте коммит A. Теперь A является текущим коммитом, и у вас есть все файлы такими, какими они были, когда вы делали A. ​​

  2. Выполните , скопировав все файлы из B, но затем переместите один из них. Затем вы делаете новый коммит, который точно так же, как B, за исключением того, что файл перемещен (и внутренняя сохраненная дата для нового улучшенного - B сделана «сейчас», а не «тогда»). «). Вы получите новый коммит, который мы можем назвать B':

    A--B--C--D
     \
      B'
    

    Родителем B' является A: стрелка, указывающая назад, которую Git использует для обратной работы от каждого коммита до тот, что был раньше, указывает на фиксацию A, так же как и B указывает на фиксацию A. Разница между B и B' заключается в том, что вы переместили файл (и, конечно, у B' другой хэш-идентификатор Git - наши буквы здесь означают реальные большие уродливые хеш-идентификаторы, которые Git компенсирует каждый новый коммит).

    Однако в этой диаграмме чего-то не хватает: какое имя указывает на B'? Ну, давайте пока не будем об этом беспокоиться. Вместо этого давайте перейдем к ...

  3. Теперь скопируйте C в C', переименовывая один файл в процессе, как вы это делали при создании B'. Родителем для C' будет B':

    A--B--C--D
     \
      B'-C'
    
  4. Повторите для D, чтобы сделать D':

    A--B--C--D
     \
      B'-C'-D'
    
  5. Пусть Git запишет хэш-идентификатор D' в имя master. Это особенно хитрая часть: теперь у вас есть:

    A--B--C--D   [abandoned]
     \
      B'-C'-D'  <-- master (HEAD)
    

    То есть, теперь имя master идентифицирует этот новый и улучшенный D' вместо старого D.

Единственная проблема, связанная с выполнением всего этого, состоит в том, что, если у любого другого пользователя Git есть копия репозитория, в котором есть последовательность фиксации A-B-C-D. Они могут создавать свои собственные коммиты поверх D, а не поверх вашего нового D'. Этот тип процесса сделает их жизни трудными, если они не готовы к этому. Поэтому, если у вас есть кто-то еще, использующий клон этого репозитория, и у них есть эти три коммита, рассмотрите , а не , делающего что-либо из этого. Но если ни у кого больше нет цепочки B-C-D, вы можете заменить их новой и улучшенной цепочкой B'-C'-D'. Или, если все остальные участники этого проекта ожидают такого рода переписывания, вы все равно можете это сделать. (Если никто не вовлечен, легко увидеть, что из всех других вовлеченных людей никто не будет возражать.)

Хорошо, так, как мы можем добиться этого переписать?

Самый простой способ - использовать git rebase -i. Эта интерактивная перебазировка позволяет вам остановить и изменить то, что будет входить в каждый новый коммит, прежде чем он фактически сделает коммит. Вы просто находите фактический хеш-идентификатор коммита, который вы хотите сохранить - в этом случае, коммит A - и, находясь на ветке master, выполните:

git rebase -i <hash>

Это вызывает ваш любимый редактор - или, по крайней мере, тот, который вы сказали Git, ваш любимый, установив core.editor - для файла с тремя командами pick. Измените каждый на edit, сохраните файл инструкций и выйдите из редактора.

Теперь Git начнет делать B' поверх A, но затем остановится и позволит вам отредактировать коммит. Выполните:

git mv file1 sample/file1

(сначала создайте каталог sample, если необходимо), затем:

git commit --amend --no-edit

, чтобы установить B' в качестве желаемого результата, затем:

[118 ]

Это будет плохо закрепить B' на месте и начать процесс копирования C, затем остановиться, так что теперь вы git mv file2 sample/file2 и git commit --amend --no-edit и git rebase --continue перейдете к шагу копирования -D. Повторите, как и раньше.

После того, как обновленные коммиты все будут сделаны и на месте, git rebase сделает последний шаг, вернув имя ветви master, чтобы указать на D' вместо D.

Просто для полноты: вот как работают промежуточные коммиты

Пока Git строит эту новую цепочку замены B'-C'-D', имя, которое находит , каждый из этих коммитов просто HEAD сам. При этом используется режим, который Git вызывает отсоединенный HEAD . Хотя это звучит страшно, это просто означает, что специальное имя HEAD, которое Git всегда требует, не привязано ни к какому имени ветви вообще.

Например, в середине перебазирования у вас есть:

A--B--C--D  <-- master
 \
  B'  <-- HEAD

По мере добавления новых коммитов вы получаете:

A--B--C--D  <-- master
 \
  B'-C'  <-- HEAD

и так далее. Когда в git rebase -i заканчиваются инструкции - pick, которые вы изменили на edit, - это инструкции, - перебазирование выполнено, и Git возвращает имя master на место, повторно присоединяя к нему HEAD и получить нам диаграмму, показанную в шаге 5.

9
задан Dhay 16 June 2017 в 15:07
поделиться

9 ответов

Обработка событий сделана ASP.NET совпадением идентификатора управления и параметров запроса. В Вашем случае TextBox, созданный во время txtTextChanged (), будет иметь автоматический идентификатор, потому что Вы не указываете явного идентификатора. Тот идентификатор будет отправлен назад во время измененного события текста.

После события загрузки страницы ASP.NET попытается найти, что управление с таким идентификатором увольняет событие за него. Очевидно, ASP.NET не сможет найти соответствие, потому что TextBox создал во время Page_Load (), отличается и имел бы другой идентификатор.

Решить это: укажите явный идентификатор для своего текстового поля:

TextBox txt = new TextBox();
txt.Text = myText;
txt.ID = "txtBox";
12
ответ дан 4 December 2019 в 10:34
поделиться

Попытайтесь создать средства управления в Page_Init () метод...

3
ответ дан 4 December 2019 в 10:34
поделиться

чтобы событие возврата стреляло, управление, которое должно запустить событие, должно быть доступным с тем же идентификатором и теми же данными по жизненному циклу обратной передачи.

Если у Вас будут статические элементы управления (определенный в Вашем aspx/ascx/master) и включенное состояние отображения, то они будут воссозданы автоволшебно.

Если Вы не хотите использовать состояние отображения или использовать динамические средства управления, необходимо связать с данными средства управления на каждом page_load, так, чтобы средства управления были в порядке как раз к событиям для увольнения (происходит после Page_load),

при изменении идентификатора родительского управления или страницы Вы могли бы случайно отбросить состояние отображения, автосвязывают, поскольку идентификаторы управления содержат идентификаторы предков. Я думаю, что необходимо быть безопасным выполнением, что, пока Вы делаете это в Page_Init (прежде чем состояние отображения будет настроено),

2
ответ дан 4 December 2019 в 10:34
поделиться

Воссоздайте динамично созданные средства управления в Page_Init. У Вас не будет доступа к данным состояния отображения управления при воссоздании его в Page_Load (состояние отображения загружается в PreLoad, который происходит перед Page_Load).

Кроме того, не забывайте присваивать идентификатор управлению.

2
ответ дан 4 December 2019 в 10:34
поделиться

У меня была подобная проблема. Я думаю, что проблема - то, что динамично созданные средства управления не сохранены в поле зрения состоянием и не переживают обратную передачу. Вот комментарий, разорванный из моего кода, который описывает решение, которое я предложил (это не может быть единственное, но это работало на меня).

Эта страница используется для определения сетки динамично. Пользователь нажимает флажки для указания который поля включать в сетку. Логика этой страницы делает две существенных вещи:

(1) Это поддерживает объект GridDefinition, который сохранен в ViewState. (2) Это восстанавливает программно добавленные средства управления (по существу все в объекте таблицы) от GridDefinition в ViewState на каждой обратной передаче. Динамично добавленные средства управления НЕ воссоздаются на обратной передаче от ViewState. Действительно, я нашел, что, если Вы не воссоздаете средства управления, их события не будут стрелять. По-видимому:

       "The process that matches controls to posted values occurs 
       after page_load completes, so it has to occur just like this 
       if you are to use this way."

Когда я получаю событие управления, указывающее на некоторое изменение в данных, я должен отразить, что изменение в объекте GridDefinition сохранило в ViewState. Тот путь, на обратной передаче NEXT, управление может быть воссоздано правильно (например, текстовое поле, указывающее на текст заголовка для столбца сетки).

1
ответ дан 4 December 2019 в 10:34
поделиться

Когда я исследовал эту проблему, это было в контексте Динамических меню, и существует набор ответов Google, которые, вместе, получили меня через него (потому что это - достаточно общее требование, я предполагаю.) У меня нет сводки ответа, но это могло бы быть полезное место для запуска (т.е. Google для Динамических меню.NET). Существует несколько вопросов здесь на этом сайте также.

0
ответ дан 4 December 2019 в 10:34
поделиться

... как другое предложение, не события привязки после Page_Load слишком поздно? и поэтому они не будут уволены в обратную передачу. возможно, что-то для проверки..

0
ответ дан 4 December 2019 в 10:34
поделиться

Мне еще раз напоминают, почему я избегаю asp - мне он походит на один уровень абстракции слишком многие. Но по аналогии с JavaScript, действительно ли возможно, что Вы заканчиваете больше чем с одним обработчиком на событии?

0
ответ дан 4 December 2019 в 10:34
поделиться

Ваш ответ, приведенный ниже, с полным кодом:

string myText = "a";

protected void Page_Load(object sender, EventArgs e)
{
    WriteRows();
}

private void WriteRows()
{
    TableRow tr = new TableRow();

    TableCell tc = new TableCell();
    TextBox txt = new TextBox();
    txt.Text = myText;

    txt.ID = "txt1";

    txt.TextChanged += new EventHandler(txt_TextChanged); // Assign event handler

    txt.AutoPostBack = true;

    tc.Controls.Add(txt);
    tr.Controls.Add(tc);

    tc = new TableCell();
    tc.Text = txt.Text;
    tr.Controls.Add(tc);

   Table1.Controls.AddAt(0,tr);

}

private void txt_TextChanged(object sender, EventArgs e)
{
    myText = ((TextBox)sender).Text;
    RedrawTable(); // Delete the row (incl. the TextBox) and rewrite it
}

private void RedrawTable()
{
    Table1.Controls.RemoveAt(0);
    WriteRows();
}
0
ответ дан 4 December 2019 в 10:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: