2016-05-29 3 views
1

ブロックajaxコールでcurrentBlockを取得する最善の方法は何ですか?ページタイプの参照なしでブロックajax呼び出しでcurrentBlockを取得する方法。 [episerver 9]

[HttpGet] 
public ActionResult GetSomething() 
{ 
    var currentBlock = Get(); //how? 
    return currentBlock.SomeLabel; 
} 

(ブロックまたはBlockControllerがページを知らないとき、私は解決策を知っていない)

私は、任意のページのためのブロックが再利用可能なようにしたいです。

ありがとうございました。

答えて

2

ブロックのコンテンツ参照を渡す必要があると思いますが、それほど悪くはありません。あなたのglobal.asaxクラスがRegisterRoutesメソッドのオーバーライドでの標準的なMVCのルートが含まれて確認してください、で開始する

public class EPiServerApplication : EPiServer.Global 
{ 
    protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 
    } 

    protected override void RegisterRoutes(RouteCollection routes) 
    { 
     base.RegisterRoutes(routes); 

     routes.MapRoute(
      name: "Default", 
      url: "{controller}/{action}/{id}", 
      defaults: new { action = "Index", id = UrlParameter.Optional }); 
    } 
} 

私は、私はいくつかの物事をテストするために使用されてきたブロックを持っています。それはTitleプロパティとItems - コンテンツ参照のリストを持っています。このブロックの

[ContentType(DisplayName = "Super Happy Fun Block", GUID = "b5d5c00c-dc8e-4ada-8319-20fd3474d4e7", Description = "")] 
public class SuperHappyFunBlock : BlockData 
{ 
    public virtual string Title { get; set; } 

    public virtual IList<ContentReference> Items { get; set; } 
} 

、私はそれらの性質プラスContentReferenceプロパティを含むビューモデルを作成します。あなたはおそらくあなたのcshtmlビューファイルの中でこれを行うことができますが、これはあなたのビューを少しきれいに保ちます。

public class SuperHappyFunModel 
{ 
    public string Title { get; set; } 

    public IList<ContentReference> Items { get; set; } 

    public ContentReference ContentLink { get; set; } 
} 

次に、ビューモデルを使用するブロックのコントローラアップワイヤー。また、いくつかのjavascriptファイルが必要になります。それらはコントローラ経由でここに追加できます。その詳細については、EpserverのドキュメントClient Resourcesを参照してください。ビューで

public class SuperHappyFunBlockController : BlockController<SuperHappyFunBlock> 
{ 
    public override ActionResult Index(SuperHappyFunBlock currentBlock) 
    { 
     ClientResources.RequireScript("https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js").AtFooter(); 
     ClientResources.RequireScript("/static/js/SuperHappyFunBlock.js").AtFooter(); 

     var model = new SuperHappyFunModel 
     { 
      Title = currentBlock.Title, 
      Items = currentBlock.Items, 
      ContentLink = (currentBlock as IContent)?.ContentLink ?? ContentReference.EmptyReference 
     }; 

     return PartialView(model); 
    } 
} 

、コンテンツ参照はJavaScriptがそれを見つけることができる場所にレンダリングされることを確認してください。 data-block-idというデータ属性を使用します。ブロックコントローラで参照

@model SuperHappyFunModel 

<div class="SuperHappyFunBlockController" data-block-id="@Model.ContentLink.ToString()"> 
    <p class="dynamic">Content goes here.</p> 
</div> 

のJavaScriptファイルには、ページ上のすべてのブロックインスタンスを探し、その後、それぞれについて、AJAX呼び出しを行う必要があります。ブロックがプロパティとしてページ上で使用されている場合、ブロックプロパティはIContentを継承しないため、ContentLinkはありません。

(function($) { 
    $('.SuperHappyFunBlockController') 
     .each(function (index, blockDiv) { 
      var $blockDiv = $(blockDiv), 
       blockId = $blockDiv.attr('data-block-id'); 
      if (!blockId) { 
       console.log('This block must be a property on a page... no block id found!'); 
       return; 
      } 
      $.ajax({ 
       method: 'GET', 
       url: '/superhappyfunblock/getsomething/' + blockId, 
       success: function (data) { 
        console.log(data); 
        $blockDiv.find('.dynamic').text(data); 
       } 
      }); 
      console.log(blockId); 
     }); 
})($); 

最後に、実行する最後のものは、コントローラ上のAjaxのメソッドを作成することです。これは、最初に追加したデフォルトのMVCビューに準拠するように、 "id"という文字列パラメータが必要になります。コントローラに依存性注入を使用して、IContentLoaderのインスタンスを取得します。

public class SuperHappyFunBlockController : BlockController<SuperHappyFunBlock> 
{ 
    public override ActionResult Index(SuperHappyFunBlock currentBlock) 
    { 
     // code omitted here for brevity... 
    } 

    private readonly IContentLoader _contentLoader; 

    public SuperHappyFunBlockController(IContentLoader contentLoader) 
    { 
     _contentLoader = contentLoader; 
    } 

    public ActionResult GetSomething(string id) 
    { 
     ContentReference blockReference; 
     if (!ContentReference.TryParse(id, out blockReference)) 
      return HttpNotFound(); 

     SuperHappyFunBlock block; 
     if (!_contentLoader.TryGet(blockReference, out block)) 
      return HttpNotFound(); 

     return Content($"This is some really cool stuff for the block named {((IContent) block).Name}."); 
    } 
} 
2

代わりに経路を追加してみませんか?したがって、URLはブロックが使用されているどこでも同じですか?または、すべてのページコントローラーの基本クラスにアクションを配置します。 次に、ブロックのビューからアクションに参照を渡す必要があります。

+1

私はヨハンの提案は良いと思いますが、あなたはまた、現在のページのコンテキストを取得するために** PageRouteHelper **クラスによって助けられることがあります。http://world.episerver.com/documentation/class-ライブラリ/?documentId = cms/8/AB460229 –

関連する問題