Pass two templates to a registration view

7

I have a sign-up access screen. I have to fill it with values registered in the database.

Follow the codes:

Models:

public partial class Aba
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Aba()
    {
        this.Tela = new HashSet<Tela>();
    }

    public int idAba { get; set; }
    public string idEmpresa { get; set; }
    public string Nome { get; set; }
    public string idAbaSistema { get; set; }

    public virtual Empresa Empresa { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Tela> Tela { get; set; }
}

public partial class Tela
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Tela()
    {
        this.TelaFuncao = new HashSet<TelaFuncao>();
    }

    public int idTela { get; set; }
    public int idAba { get; set; }
    public string Nome { get; set; }
    public string idTelaSistema { get; set; }

    public virtual Aba Aba { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<TelaFuncao> TelaFuncao { get; set; }
}

public partial class TelaFuncao
{
    public int idTelaFuncao { get; set; }
    public int idTela { get; set; }
    public string Nome { get; set; }
    public string idFuncaoSistema { get; set; }

    public virtual Tela Tela { get; set; }
}

Controller:

var abas = _abaApp.SelectForeignKey("s8f50f03-c064-4afa-ba5e-397236cd2b03");
return View(abas);

Repository:

var abaQuery = _sigconEntities.Aba
                .Where(a => a.idEmpresa == idEmpresa);
return abaQuery.ToList();

View:

@model Sigcon.Model.Acesso

@{
    ViewBag.Title = "Cadastrar";
}

The problem is to send the model of these values to the view , it is already "typed", I do not know how to send the two values.

Thank you in advance!

    
asked by anonymous 22.05.2016 / 02:28

1 answer

8

Following the previous hook, if you have the ratio of Aba to Tela , the selection made here already contemplates the lazy load of Tela and TelaFuncao :

var abaQuery = _sigconEntities.Aba
                .Where(a => a.idEmpresa == idEmpresa);
return abaQuery.ToList();

@model of your View , so it needs to be:

@model IEnumerable<Sigcon.Model.Aba>

@{
    ViewBag.Title = "Cadastrar";
}

And the fill:

@foreach (var aba in Model)
{
    <h1>Aba: @aba.Nome</h1>

    foreach (var tela in aba.Telas) 
    {
        <h2>Tela: @tela.Nome</h1>

        foreach (var permissao in tela.TelaFuncoes)
        {
            <p>Permissão: @permissao.Nome</p>
        }
    }
}

But since you want a creation and editing form, the solution will necessarily be more complex. I will try to make a succinct answer covering all points.

First of all, we are dealing with a screen with multiple cardinalities. My suggestion is that you first make a screen whose Model is Tela , and for it you can deal with N Models of type TelaFuncao . Starting with Aba will make the solution very complex for you that is starting.

So, I've taken some liberties and I'm going to reimplement your system with a couple of adjustments, starting with the Models :

public class TelaFuncao
{
    [Key]
    public Guid TelaFuncaoId { get; set; }
    public Guid TelaId { get; set; }

    [Required]
    public string Nome { get; set; }

    public virtual Tela Tela { get; set; }
}

public class Tela
{
    [Key]
    public Guid TelaId { get; set; }
    public Guid AbaId { get; set; }

    [Required]
    public string Nome { get; set; }

    public virtual Aba Aba { get; set; }
    public virtual ICollection<TelaFuncao> TelaFuncoes { get; set; }
}

public class Aba
{
    [Key]
    public Guid AbaId { get; set; }
    public Guid EmpresaId { get; set; }

    [Required]
    public string Nome { get; set; }

    public virtual Empresa Empresa { get; set; }
    public virtual ICollection<Tela> Telas { get; set; }
}

public class Empresa
{
    [Key]
    public Guid EmpresaId { get; set; }

    [Required]
    public string Nome { get; set; }

    public virtual ICollection<Aba> Abas { get; set; }
}

Note also that I'm using Guid of purpose, to the detriment of int , in setting the keys. There are some advantages to using that can be found here .

I did this because I want to use the Entity Framework naming conventions and automatically generate everything using Scaffolding . Once this is done, we can generate Controllers and Views through the IDE.

To do this, once you have set the 4 Models , right-click on the Controllers directory and choose the Add > Controller ... :

Onthenextscreen,chooseMVC5ControllerwithViews,usingEntityFramework:

Next,definetheModelclass,thedatacontextclass,andtheControllername.HereImadeittoEmpresa.Itlookslikethis:

ByclickingAdd,theresultshouldbe:

Notethatnotonlytheselection,drill-down,inclusion,edit,anddeletelogicweregenerated,butalsothecorrespondingViewsofeachoperation.

Repeattheprocessfortabs,screens,andscreenfunctions.

Oncethisisdone,youwillneedtoinstallapackagecalled BeginCollectionItem . I've told you a lot about it here , so I'll skip some parts.

Open the Package Manager Console ( View > Other Windows > Package Manager Console ) and install -O.

OpenTelasController(I'massumingyou'vealreadygeneratedit)andViews/Telas/Create.cshtml.Let'sstartwithView.Mineislikethis:

@modelMeuProjeto.Models.Tela@{ViewBag.Title="Create";
}

<h2>Create</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Tela</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.AbaId, "AbaId", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("AbaId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.AbaId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Nome, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Nome, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Between the "Create" button and the last field, Nome , place a Partial call declaration like this:

    <div class="form-group">
        @Html.LabelFor(model => model.Nome, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Nome, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
        </div>
    </div>

    @Html.Partial("_Permissoes", Model.TelaFuncoes)

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>

That is, we are sending to another View (in this case, a partial View ) only TelaFuncoes . There we will build our whitelist.

Create a Partial named "_Permissoes":

Putthefollowingintoit:

@modelIEnumerable<MeuProjeto.Models.TelaFuncao><divclass="actions">
    <a class="btn btn-default btn-sm" id="adicionar-nova-permissao">
        Adicionar Nova Permissão
    </a>
    <script type="text/javascript">
                $("#adicionar-nova-permissao").click(function () {
                    $.get('/Telas/NovaLinhaPermissao', function (template) {
                        $("#area-permissoes").append(template);
                    });
                });
    </script>
</div>

<div id="area-permissoes">
    @if (Model != null)
    {
        foreach (var permissao in Model)
        {
            @Html.Partial("_LinhaPermissao", permissao);
        }
    }
</div>

Well, if you read the code, you'll notice that we'll need another Partial named _LinhaPermissao . Create this Partial and put the following into it:

@model MeuProjeto.Models.TelaFuncao

@using (Html.BeginCollectionItem("TelaFuncoes"))
{
    <div class="form-group">
        @Html.HiddenFor(model => model.TelaFuncaoId)
        @Html.HiddenFor(model => model.TelaId)

        <label class="col-md-1 control-label">Nome</label>
        <div class="col-md-5">
            @Html.TextBoxFor(model => model.Nome, new { @class = "form-control", placeholder = "Nome" })
            @Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
        </div>
        <div class="col-md-2">
            <a class="btn red" onclick="$(this).parent().parent().remove();">Excluir</a>
        </div>
    </div>
}

If you did everything right, the screen should look like this:

Ifyounoticed,inourTelasController,weneedtoaddamethodcalledNovaLinhaPermissao.Itlookslikethis:

publicActionResultNovaLinhaPermissao(){returnPartialView("_LinhaPermissao", new TelaFuncao { TelaFuncaoId = Guid.NewGuid() });
    }

And now we can add and delete permissions.

Andwhenweadd3permissionsandsendtoCreateofTelasController,wehavethe3permissionsthere.

As an exercise, edit now. If you need help, open another question (this one is already too big).

PS: Delete a repository of your architecture. The Entity Framework is already a repository.

    
22.05.2016 / 02:44