MVC sem Dicionário de Dados

Eu já falei em algum outro texto que o MVC trabalha com estrutura de dados independente de dicionário. Na teoria isso é lindo, mas na pratica surgem muitas duvidas. Essa semana um amigo me questionou sobre o assunto e a conversa deu origem a esse post, espero que seja útil pra muitos Devs.

Quando falamos de estrutura de dados no MVC enxergamos automaticamente o Dicionário de Dados e porquê isso? Porque a estrutura tem campos, índices, gatilhos, pastas e grupos, igualzinho o Dicionário com o SX3, SX2, SX7 e afins. Todavia quando eu falo que a estrutura é independente de dicionário, eu quero dizer que:

  • Você pode criar campos que não existem no dicionario, como por exemplo campos de legenda, botão, imagem, entre outros;
  • Você pode criar uma estrutura inteiramente independente de dicionário de dados para ser utilizada no seu FormField ou FormGrid.

Esse post tem por objetivo mostrar a segunda opção, que é um modelo de dados totalmente independente de dicionário.

Mão na Massa!

O exemplo que vou usar aqui é uma rotina MVC para copiar um arquivo de uma pasta para outra, sim, normalmente um MVC é usado em cadastros, mas minha criatividade quis fazer um programa para realizar a copia do arquivo.

Meu programa vai ser bem simples, apenas com um FormField, não teremos grid aqui, mas a estrutura é igual para os dois componentes, então se você quiser um grid, vai conseguir chegar no seu objetivo se entender o funcionamento.

A estrutura de dados no Model é um objeto do tipo FWFormModelStruct, no componente é possível criar campo, gatilho e índice, a documentação de cada método você encontra no TDN nesse link.  No meu exemplo vou criar apenas 4 campos, da seguinte forma:

static function getModelStruct()
Local oStruct := FWFormModelStruct():New()
 
 oStruct:AddField('Arquivo Origem','Arquivo Origem' , 'ARQ', 'C', 50, 0, , , {}, .T., , .F., .F., .F., , )
 oStruct:AddField('Carregar','Carregar' , 'LOAD', 'BT', 1, 0, { |oMdl| getArq(oMdl), .T. }, , {}, .F., , .F., .F., .F., , )
 oStruct:AddField('Caminho de Destino','Caminho de Destino' , 'DEST', 'C', 50, 0, , , {}, .T., , .F., .F., .F., , )
 oStruct:AddField('Selecionar','Selecionar' , 'LOAD2', 'BT', 1, 0, { |oMdl| getDir(oMdl), .T. }, , {}, .F., , .F., .F., .F., , )
 
return oStruct

 

Para mostrar o formulário na View, vai ser necessário criar uma estrutura de dados também, a estrutura da View permite criar campos, pastas e grupos, se quiser se aventurar pelas opções dê uma olhada nesse link que encontrá toda a documentação da classe FWFormViewStruct.

Detalhe importante a ser considerado, o ID do campo na View e no Model devem ser iguais, por exemplo, no model meus campos foram identificados como “ARQ”, “LOAD”, “DEST” e “LOAD2”, veja abaixo que os IDs são iguais para a estrutura da View.

static function getViewStruct()
Local oStruct := FWFormViewStruct():New()

oStruct:AddField( 'ARQ','1','Arquivo Origem','Arquivo Origem',, 'Get' ,,,,.F.,,,,,,,, )
 oStruct:AddField( 'LOAD','2','Carregar','Carregar',, 'BT' ,,,,,,,,,,,, )
 oStruct:AddField( 'DEST','3','Destino','Destino',, 'Get' ,,,,.F.,,,,,,,, )
 oStruct:AddField( 'LOAD2','4','Selecionar','Selecionar',, 'BT' ,,,,,,,,,,,, )

return oStruct

Pronto, com esses dois objetos você consegue criar uma estrutura de dados independe de dicionário, no meu exemplo uso a estrutura em um objeto do tipo FormField, mas nada impede de você usar em um grid.

 

Mas é só isso? Fim?

É.. quase. Acompanhe meu raciocínio lógico.

Quando você cria uma estrutura baseada em dicionário, o MVC sabe qual tabela deve olhar para carregar os dados e também para gravar, exemplo, se você usa no MVC a tabela SA1, o MVC sabe que os dados virão da tabela SA1 e sabe que a gravação deve ocorrer na tabela SA1.

Quando você decide usar uma estrutura sem dicionário, como o MVC sabe de onde carregar e onde gravar os dados? A resposta é que o MVC não sabe.

Se a sua estrutura de dados não é baseada em uma tabela conhecida no dicionario, então é necessário informar para o MVC deonde/como os dados são carregados e como/onde deve ser feita a gravação.

Fica calmo(a) que isso não é a coisa mais complicada do mundo.

Para definir o Load você vai usar o 6º parametro do método AddFields (se for um Field)  ou o 8º parametro do método AddGrid (se for um Grid). O parâmetro deve enviar para o MVC um bloco de código que retorne um array com os dados que devem ser carregados para o modelo (isso ocorre em qualquer operação diferente de inclusão).

Os dados devem ser colocados exatamente na ordem dos campos da estrutura de dados, ou seja, se a sua estrutura tem o campo A, B e C (nessa ordem), os dados devem corresponder aos campos A, B e C, exatamente nessa ordem.

Exemplo de função com o FormField:

bLoad := {|oFieldModel, lCopy| loadField(oFieldModel, lCopy)}

oModel:addFields('ZA1MASTER',,oStruZA1,bPre,bPos,bLoad)


Static Function loadField(oFieldModel, lCopy)
Local aLoad := {}

   aAdd(aLoad, {xFilial("ZA1"), "000001", "Musica 1", Date(), "R"}) //dados
   aAdd(aLoad, 1) //recno
      
Return aLoad
Exemplo de Load com o FormGrid:

bLoad := {|oGridModel, lCopy| loadGrid(oGridModel, lCopy)}

oModel:AddGrid( 'ZA2DETAIL', 'ZA1MASTER', oStruZA2,, , , ,bLoad)

Static Function loadGrid(oGridModel, lCopy)
Local aLoad := {}

   aAdd(aLoad,{0,{xFilial("ZA2"), "000001", "01", "000100","AUTOR1","AUTOR"}})
   aAdd(aLoad,{0,{xFilial("ZA2"), "000001", "02", "000102","AUTOR2","AUTOR"}})
   aAdd(aLoad,{0,{xFilial("ZA2"), "000001", "03", "000104","AUTOR3","AUTOR"}})
   aAdd(aLoad,{0,{xFilial("ZA2"), "000001", "04", "000105","AUTOR4","AUTOR"}})
   aAdd(aLoad,{0,{xFilial("ZA2"), "000001", "05", "000106","AUTOR5","AUTOR"}})

Return aLoad

Se quiser saber mais sobre os métodos AddField e AddGrid acesse esse link.

Agora só falta o Commit, que é a parte do código responsável pela gravação dos dados do modelo. O Commit é um bloco passado no  4º parâmetro do método New do Model e é possivel substituir o bloco de Commit para realizar procedimentos antes ou depois da gravação do MVC. Se o seu modelo é gravado parte por você e parte pelo MVC, não esqueça de chamar a função FWFormCommit, caso contrario, sua gravação não vai funcionar corretamente.

Coloquei no gitHub o exemplo completo do programa sem dicionário de dados, se quiser acessar é só olhar aqui.

Aceito sugestões de temas para os próximos posts!

[]s Juliane

 

 

 

 

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s