Регистрация  |  Вход

VIsualforce для начинающих

Здравствуйте! Есть такая проблема:
Вступление. Есть некоторая таблица, в которую можно добавить записи. Напротив каждой добавленной записи есть кнопка Delete(самописная, с отлавливанием Id записи и последующим удалением).
Проблема: После нажатия кнопки Delete запись удаляется, но таблица не отображает изменения, т.е если заново перейти на страницу приложения, то все отображается корректно. Если не переходить, таблица не реагирует на нажатие. rerender есть.
Теже грабли с кнопкой quick save, но она объявляется как компонент стандартного контроллера. Опять таки, всё работает и отображается корректно в случае обновления страницы. На лету - нет.
Заранее извиняюсь за такие вопросы, человек я в salesforce новый, но всё же, хотелось бы разобраться. С большей частью приложения, благодаря этому прекрасному форуму и воркбуках, справился.

Здравствуйте! Есть такая проблема:
Вступление. Есть некоторая таблица, в которую можно добавить записи. Напротив каждой добавленной записи есть кнопка Delete(самописная, с отлавливанием Id записи и последующим удалением).
Проблема: [u]После нажатия кнопки Delete запись удаляется, но таблица не отображает изменения, т.е если заново перейти на страницу приложения, то все отображается корректно. Если не переходить, таблица не реагирует на нажатие. rerender есть[/u].
Теже грабли с кнопкой quick save, но она объявляется как компонент стандартного контроллера. Опять таки, всё работает и отображается корректно в случае обновления страницы. На лету - нет.
Заранее извиняюсь за такие вопросы, человек я в salesforce новый, но всё же, хотелось бы разобраться. С большей частью приложения, благодаря этому прекрасному форуму и воркбуках, справился.

У меня было что-то похожее, может быть твой случай:

Если хочешь чтобы "ререндернулся" какой-то видимый элемент (таблица, блок), то надо выбирать для rerender ID блока на уровень выше.

Например если есть таблица, то надо обернуть ее в
<apex:outputPanel layout="block" id="rerender_me">...</apex:outputPanel>
и обновить именно этот блок.

О, и еще вспомнил по ходу:
смотри - таблица у тебя строится по какому-то листу, который ты заполняешь в конструкторе. При вызове метода для удаления, удаляется элемент из базу, но в листе он остается и если ты после удаления заново не перестроишь лист или не удалишь вручную из листа, то таблица у тебя так же и построится, с теми же элементами. И конечно после перезагрузки лист опять построится из базы уже по актуальным данным.

У меня было что-то похожее, может быть твой случай:

Если хочешь чтобы "ререндернулся" какой-то видимый элемент (таблица, блок), то надо выбирать для rerender ID блока на уровень выше.

Например если есть таблица, то надо обернуть ее в 
<apex:outputPanel layout="block" id="rerender_me">...</apex:outputPanel>
и обновить именно этот блок.

О, и еще вспомнил по ходу:
смотри - таблица у тебя строится по какому-то листу, который ты заполняешь в конструкторе. При вызове метода для удаления, удаляется элемент из базу, но в листе он остается и если ты после удаления заново не перестроишь лист или не удалишь вручную из листа, то таблица у тебя так же и построится, с теми же элементами. И конечно после перезагрузки лист опять построится из базы уже по актуальным данным.

Dmitry Shnyrev
У меня было что-то похожее, может быть твой случай:

Если хочешь чтобы "ререндернулся" какой-то видимый элемент (таблица, блок), то надо выбирать для rerender ID блока на уровень выше.

Например если есть таблица, то надо обернуть ее в
<apex:outputPanel layout="block" id="rerender_me">...</apex:outputPanel>
и обновить именно этот блок.

О, и еще вспомнил по ходу:
смотри - таблица у тебя строится по какому-то листу, который ты заполняешь в конструкторе. При вызове метода для удаления, удаляется элемент из базу, но в листе он остается и если ты после удаления заново не перестроишь лист или не удалишь вручную из листа, то таблица у тебя так же и построится, с теми же элементами. И конечно после перезагрузки лист опять построится из базы уже по актуальным данным.


т.е, если я правильно понимаю:
1. Вызывается метод удаления
2. Создается переменная типа List<table>, которой присваивается значение select * from table where Id = :selectId //кактотак
3. Проверка длины переменной, дабы не словить null
4. Вернуть обновленный List<table> (?????)
Только вот update List<table> не прокатывает, либо я не понимаю каких-то простейших основ

[quote="Dmitry Shnyrev"]У меня было что-то похожее, может быть твой случай:

Если хочешь чтобы "ререндернулся" какой-то видимый элемент (таблица, блок), то надо выбирать для rerender ID блока на уровень выше.

Например если есть таблица, то надо обернуть ее в 
<apex:outputPanel layout="block" id="rerender_me">...</apex:outputPanel>
и обновить именно этот блок.

О, и еще вспомнил по ходу:
смотри - таблица у тебя строится по какому-то листу, который ты заполняешь в конструкторе. При вызове метода для удаления, удаляется элемент из базу, но в листе он остается и если ты после удаления заново не перестроишь лист или не удалишь вручную из листа, то таблица у тебя так же и построится, с теми же элементами. И конечно после перезагрузки лист опять построится из базы уже по актуальным данным.[/quote]
т.е, если я правильно понимаю:
1. Вызывается метод удаления
2. Создается переменная типа List<table>, которой присваивается значение select * from table where Id = :selectId //кактотак
3. Проверка длины переменной, дабы не словить null
4. Вернуть обновленный List<table> (?????)
Только вот update List<table> не прокатывает, либо я не понимаю каких-то простейших основ

Что-то ты совсем какой-то бред написал.

когда я говорил про table - я имел в виду тег на Visualforce странице который ты пытаешься обновить (сделать "rerender")

когда я говорил про List - это уже про apex class (controller) это список того что ты хочешь вывести на странице.

Как ты это все уместил в List<table> вообще не понял?

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

Что-то ты совсем какой-то бред написал. 

когда я говорил про table - я имел в виду тег на Visualforce странице который ты пытаешься обновить (сделать "rerender")

когда я говорил про List - это уже про apex class (controller) это список того что ты хочешь вывести на странице.

Как ты это все уместил в List<table> вообще не понял? :)

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

Не то, чтобы бред, но мысли выразил непонятным образом
Суть сводится к тому, что я пока(!) не знаю, как "после удаления заново не перестроишь лист или не удалишь вручную из листа". Напрашивается только варварский метод после удаления рефреш страницы сделать:D
Да чего обижаться, я меньше недели в данном направлении)
p.s quicksave теперь работает как надо

Не то, чтобы бред, но мысли выразил непонятным образом :)
Суть сводится к тому, что я пока(!) не знаю, как "после удаления заново не перестроишь лист или не удалишь вручную из листа". Напрашивается только варварский метод после удаления рефреш страницы сделать:D
Да чего обижаться, я меньше недели в данном направлении)
p.s quicksave теперь работает как надо

mesandman
Напрашивается только варварский метод после удаления рефреш страницы сделать:D

ну это кстати хороший метод.
mesandman
Суть сводится к тому, что я пока(!) не знаю, как "после удаления заново не перестроишь лист или не удалишь вручную из листа".

Тут все просто - в конструкторе ты данные получаешь? чтобы вывести из на странице?
Вот после delete надо тоже самое сделать, еще раз данные достать из базы - копипаст.
А лучше вынести в отдельный метод все из конструктора (из конструктора вызывать этот метод) и после удаления еще раз вызвать этот метод

[quote="mesandman"] Напрашивается только варварский метод после удаления рефреш страницы сделать:D [/quote]
ну это кстати хороший метод.  :)
[quote="mesandman"]Суть сводится к тому, что я пока(!) не знаю, как "после удаления заново не перестроишь лист или не удалишь вручную из листа". [/quote]
Тут все просто - в конструкторе ты данные получаешь? чтобы вывести из на странице?
Вот после delete надо тоже самое сделать, еще раз данные достать из базы - копипаст.
А лучше вынести в отдельный метод все из конструктора (из конструктора вызывать этот метод) и после удаления еще раз вызвать этот метод

Переделал метод Delete - работает как надо:)

Однако возник вопрос с тестами:

public static testMethod void deletetest() { 
List<Product__c> products = new List<Product__c>();
ApexPages.StandardController sc = new ApexPages.StandardController(products);
ProductsController cont = new ProductsController(sc);
Product__c p = new Product__c(Name = 'll', Type__c = 'll', Price__c = 10.00);
insert p;
products.add(p);
string selectRecordId = p.Id;
integer i=0;
cont.products = products;
cont.DeleteRecord();
}

Выдает ошибку
Error: Compile Error: Constructor not defined: [ApexPages.StandardController].<Constructor>(LIST<Product__c>) at line 15 column 43

Изучил похожую проблему https://developer.salesforce.com/forums/ForumsMain?id=906F000000093gBIAQ
Не совсем понимаю, что я делаю не так

Переделал метод Delete - работает как надо:)

Однако возник вопрос с тестами:
[code]  public static testMethod void deletetest() { 
        List<Product__c> products = new List<Product__c>();
        ApexPages.StandardController sc = new ApexPages.StandardController(products);
        ProductsController cont = new ProductsController(sc);  
        Product__c p = new Product__c(Name = 'll', Type__c = 'll', Price__c = 10.00);
        insert p; 
        products.add(p); 
        string selectRecordId = p.Id; 
        integer i=0;
        cont.products = products;
        cont.DeleteRecord(); 
}
[/code]
Выдает ошибку
[code]Error: Compile Error: Constructor not defined: [ApexPages.StandardController].<Constructor>(LIST<Product__c>) at line 15 column 43		
[/code]
Изучил похожую проблему https://developer.salesforce.com/forums/ForumsMain?id=906F000000093gBIAQ
Не совсем понимаю, что я делаю не так

Решил проблему таким образом:

public static testMethod void deletetest() { 
List<Product__c> products = new List<Product__c>{};
Product__c p = new Product__c(Name = 'll', Type__c = 'desll', Price__c = 10.00);
test.startTest();
insert p;
ApexPages.StandardController sc = new ApexPages.StandardController(p);
ProductsController controller = new ProductsController(sc);
products.add(p);
string selectRecordId = p.Id;
integer i=0;
controller.DeleteRecord();
test.stopTest();
}

Решил проблему таким образом:
[code] public static testMethod void deletetest() { 
        List<Product__c> products = new List<Product__c>{};   
        Product__c p = new Product__c(Name = 'll', Type__c = 'desll', Price__c = 10.00);
        test.startTest();        
        insert p; 
        ApexPages.StandardController sc = new ApexPages.StandardController(p);
        ProductsController controller = new ProductsController(sc);     
        products.add(p); 
        string selectRecordId = p.Id; 
        integer i=0;   
        controller.DeleteRecord();
        test.stopTest();
}
[/code]

mesandman
Решил проблему таким образом:

Правильно решил
Вот по документации
ApexPages.StandardController sc = new ApexPages.StandardController(sObject);

Подразумевается что на вход надо подать sObject, т.е. объект, а не List объектов
mesandman
ApexPages.StandardController sc = new ApexPages.StandardController(p);
ProductsController controller = new ProductsController(sc);
products.add(p);
string selectRecordId = p.Id;
integer i=0;
controller.DeleteRecord();
test.stopTest();

А у тебя в этом куске точно все нормально?
зачем тебе products, selectRecordId, i если ты их не используешь (не передаешь в инстанс контроллера)?
В предыдущем примере у тебя было: cont.products = products; вот это было правильно, но потом строчка эта пропала. Почему?

[quote="mesandman"]Решил проблему таким образом: [/quote]
Правильно решил :)
Вот по документации
[quote]ApexPages.StandardController sc = new ApexPages.StandardController(sObject);[/quote]
Подразумевается что на вход надо подать sObject, т.е. объект, а не List объектов[quote="mesandman"]ApexPages.StandardController sc = new ApexPages.StandardController(p);
        ProductsController controller = new ProductsController(sc);     
        products.add(p); 
        string selectRecordId = p.Id; 
        integer i=0;   
        controller.DeleteRecord();
        test.stopTest();[/quote]
А у тебя в этом куске точно все нормально?
зачем тебе products, selectRecordId, i если ты их не используешь (не передаешь в инстанс контроллера)? 
В предыдущем примере у тебя было: cont.products = products; вот это было правильно, но потом строчка эта пропала. Почему?

Dmitry Shnyrev
А у тебя в этом куске точно все нормально?
зачем тебе products, selectRecordId, i если ты их не используешь (не передаешь в инстанс контроллера)?
В предыдущем примере у тебя было: cont.products = products; вот это было правильно, но потом строчка эта пропала. Почему?

Почему не использую.DeleteRecord использует selectRecordId;вот на счет остального призадумался.

Дошло. в тесте она не используется.В куске все нормально.

[quote="Dmitry Shnyrev"]А у тебя в этом куске точно все нормально? 
зачем тебе products, selectRecordId, i если ты их не используешь (не передаешь в инстанс контроллера)? 
В предыдущем примере у тебя было: cont.products = products; вот это было правильно, но потом строчка эта пропала. Почему?[/quote]
Почему не использую.DeleteRecord использует selectRecordId;вот на счет остального призадумался.

Дошло. в тесте она не используется.В куске все нормально.

mesandman
Почему не использую.DeleteRecord использует selectRecordId;

Dmitry Shnyrev
string selectRecordId = p.Id;
integer i=0;
controller.DeleteRecord();
test.stopTest();

И как же у тебя в DeleteRecord() из контроллера может использоваться selectRecordId, который ты объявляешь в тестах? Это разные области видимости. Я не вижу чтобы ты передавал selectRecordId в controller чтобы потом DeleteRecord() из него взял твою переменную.

[quote="mesandman"]Почему не использую.DeleteRecord использует selectRecordId;[/quote]

[quote="Dmitry Shnyrev"]
string selectRecordId = p.Id; 
integer i=0; 
controller.DeleteRecord(); 
test.stopTest();[/quote]

И как же у тебя в DeleteRecord() из контроллера может использоваться selectRecordId, который ты объявляешь в тестах? Это разные области видимости. Я не вижу чтобы ты передавал selectRecordId в controller чтобы потом DeleteRecord() из него взял твою переменную.

Dmitry Shnyrev
И как же у тебя в DeleteRecord() из контроллера может использоваться selectRecordId, который ты объявляешь в тестах? Это разные области видимости. Я не вижу чтобы ты передавал selectRecordId в controller чтобы потом DeleteRecord() из него взял твою переменную.

Дошло. в тесте она не используется.В куске все нормально.

[quote="Dmitry Shnyrev"]И как же у тебя в DeleteRecord() из контроллера может использоваться selectRecordId, который ты объявляешь в тестах? Это разные области видимости. Я не вижу чтобы ты передавал selectRecordId в controller чтобы потом DeleteRecord() из него взял твою переменную.[/quote]

[quote]Дошло. в тесте она не используется.В куске все нормально.[/quote]