2017-08-29 11 views
0

これは古い質問のようなものかもしれませんが、Webで説明されている他のものとは異なるため、私はいくつかのタブをブートストラップに持っていますが、これはヒットするアクションに応じてアクティブに設定する必要があります。サブタブもあります。サブタブも同様にヒットするアクションに応じてアクティブに設定する必要があります。サブタブがアクティブにされているときだから、親タブがあまりにもアクティブにする必要がありASP.NET MVCで起動しているブートストラップタブを設定する

:ここ

は、それがどのように見えるかの画像です。

enter image description here

だから、私は、各アクションのPAGEIDを保存し、私がアクティブかどうかに設定することができますビューにPAGEIDに応じて、新しい属性を作成するために考えた:ここ

は属性であります:ここでは

public class YcoPageId : Attribute 
{ 
    public YcoPageId(int pageId) 
    { 
     PageId = pageId; 
    } 
    public int PageId { get; } 
} 

はアクションです:

[YcoPageId(1)] 
public ActionResult Admin() 
{ 
    return View(); 
} 

ビューでは、タブとサブタブをアクティブにするかどうかを確認するための拡張メソッドを作成したいと思います!ここで

は私のコードです:

public static bool IsActive(this HtmlHelper htmlHelper, params int[] ids) 
{ 
    var viewContext = htmlHelper.ViewContext; 
    var action = viewContext.... 
    //How to get the YcoPageId attribute from here and see the Id 
    //Here i will test if ids contain id but dont know how to get it... 
} 

各ページのIDを追加することは悪い考えだと思うなら、私はそれをするための識別子のようになりますので、私の場合のために、私は他の目的のために、このIDを使用すると思います特定のアクション...

私の質問は、どのように私の拡張メソッドの現在のアクションのための属性YcoPageIdを得ることができますか?

ビューは次のようになります。この問題を解決するためにどのように任意のより良いアイデアがある

<li class="@(Html.IsActive(1, 4, 5... etc)? "active" : "")"> 
    <a href="@url"> 
     <div class="row text-center"> 
      <div class="col-md-12"> 
       <i class="fa @fontAwesomeIcon fa-4x" aria-hidden="true"></i> 
       <br/>@menuName 
      </div> 
     </div> 
    </a> 
</li> 

場合は先に行くしてください!

ありがとうございます!

+0

これらのタブの関係はどうなっていますか?上部のタブはコントローラに関連し、サブタブは選択されたコントローラのアクションメソッドに関連していますか? –

+0

いいえ、私はいくつかのASP.NET WebformsコードをASP.MVCに移行しているので、私は関係の種類を作成することができるので、彼らは関係を持っていません。 –

+0

@StephenMueckeしかし、私はそれを考えています親タブ用のコントローラを作るのは意味がありますが、これはアクション名のサブタブをテストする一方で、コントローラ名の親タブは、説明しようとしているものですか? –

答えて

0

は、この問題に対する私の解決策である。まず、下記のようなのActionFilter属性作成

public class YcoPageIdAttribute : ActionFilterAttribute 
{ 
    public YcoPageIdAttribute(int pageId) 
    { 
     PageId = pageId; 
    } 
    public int PageId { get; } 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     if (filterContext.Result is ViewResult) 
     { 
      filterContext.Controller.TempData[DomainKeys.ViewPageId] = PageId; 
     } 
     else 
     { 
      throw new Exception("Only ViewResult has unique id"); 
     } 
     base.OnActionExecuted(filterContext); 
    } 
} 

をその後、私の行動は、この1のようになります。

[YcoPageId(1)] 
public ActionResult Admin() 
{ 
    return View(); 
} 

私が作成しました以下のような拡張方法:

public static bool IsActive(this HtmlHelper htmlHelper, params int[] ids) 
{ 
    var viewContext = htmlHelper.ViewContext; 
    return viewContext.TempData.ContainsKey(DomainKeys.ViewPageId) && 
     int.Parse(viewContext.TempData.Peek(DomainKeys.ViewPageId).ToString()).In(ids); 
} 

私はアクションのIDを知っているので、今、私は唯一のビューで以下のようにコードを配置する必要があります。

<li class="@(Html.IsActive(1)? "active" : "")"> 
    <a href="@url"> 
     <div class="row text-center"> 
      <div class="col-md-12"> 
       <i class="fa @fontAwesomeIcon" aria-hidden="true"></i> 
       <br /><small>@menuName</small> 
      </div> 
     </div> 
    </a> 
</li> 

私は以下のような重複した値とアクションを持っているかどうかを確認するために、起動時に別の方法を作りました。私も、データベースから1つのIDからアクションを識別できるように:)

public static void CheckForDuplicateActionId() 
{ 
    Assembly asm = Assembly.GetExecutingAssembly(); 
    var controllerActionlist = asm.GetTypes() 
     .Where(type => typeof(Controller).IsAssignableFrom(type)) 
     .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | 
              BindingFlags.Public)) 
     .Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), 
      true).Any()) 
     .Where(m => m.GetCustomAttribute<YcoPageIdAttribute>() != null) 
     .Select(
      x => 
       new 
       { 
        Controller = x.DeclaringType.Name, 
        Area = x.DeclaringType.FullName, 
        Action = x.Name, 
        ReturnType = x.ReturnType.Name, 
        Id = x.GetCustomAttribute<YcoPageIdAttribute>().PageId 
       }) 
     .ToList(); 
    var actionIds = controllerActionlist.Select(x => x.Id).ToList(); 
    var actionIdsGrouped = actionIds.GroupBy(x => x).Where(x => x.Count() > 1).ToList(); 
    if (!actionIdsGrouped.IsNullOrEmpty()) 
    { 
     StringBuilder error = new StringBuilder(""); 
     actionIdsGrouped.ForEach(actionId => 
     { 
      var actions = controllerActionlist.Where(x => x.Id == actionId.Key); 
      actions.ForEach(a => 
      { 
       error.Append(
        $" | Id : {a.Id}, Action Name: {a.Action}, Controller Name : {a.Controller}, Location : {a.Area}. "); 
      }); 
     }); 
     var maxId = controllerActionlist.Max(x => x.Id); 
     error.Append(
      "PLease consider changing the the duplicated id - Here are some options to choose from : Id {"); 
     for (int i = 1, j = 1; i < maxId + 5; i++) 
     { 
      if (actionIds.Contains(i)) continue; 
      if (j < 5) 
      { 
       error.Append(i + ","); 
       j++; 
      } 
      else 
      { 
       error.Append(i + "}"); 
       break; 
      } 
     } 
     throw new Exception(
      $"There are more than one action duplicated with the same Id, The action data are as below : {error}"); 
    } 
} 

たぶん私は今、それが良い働いているデータベース内のすべてのこれらのデータを追加します。

0

私が正しく理解している場合は、各ページ/ビューのIDを作成し、それをページ/ビューで使用して、メニュータブをアクティブに設定するCSSクラスを動的に設定しようとしています。その場合は...コントローラーでIDを設定するのではなく、次のようなコードで共有ビューを作成するのはどうでしょう... -

ビューでは、次のようにRazor/C#コード。

@{ 
 
     var iPageId = 0 
 
     var sViewPath = ((System.Web.Mvc.BuildManagerCompiledView)ViewContext.View).ViewPath; 
 
     
 
     //for example 
 
     if (sViewPath.ToLower.IndexOf("admin") >= 0) 
 
     { 
 
      iPageId = 1; 
 
     } 
 
     else if (sViewPath.ToLower.IndexOf("dashboard") >= 0) 
 
     { 
 
      iPageId = 2; 
 
     } 
 
     else if (sViewPath.ToLower.IndexOf("vessels") >= 0) 
 
     { 
 
      iPageId = 3; 
 
     } 
 
     else if (sViewPath.ToLower.IndexOf("reports") >= 0) 
 
     { 
 
      iPageId = 4; 
 
     } 
 
    }

次のスニペットと一次ビューで共有ビューをレンダリングします。

@Html.Partial("~/Views/Menu/_SharedViewName.cshtml")

は、その後、あなたは主のページ/ビュー(秒)で変数のどこ iPageIdにアクセスし、それに応じて、あなたのCSSクラスを設定することができるはずです。ここで

関連する問題