2015-02-04 8 views
1

두 개의 필드가있는 UI를 통해 (예 : 모듈이 아닌) 사용자 정의 콘텐츠 유형이 있습니다. 그 중 하나는 ContentItemPicker입니다. 모델의 컬렉션에서 ContentItem에 대한 친숙한 URL을 찾는 것 외에는 프런트 엔드에서 모든 작업을 처리했습니다.과수원 ContentItem의 AutoroutePart 표시 URL

@using Orchard.ContentPicker.Fields 
@using Orchard.Utility.Extensions; 
@using System.Linq 
@using Orchard.ContentManagement; 
@using Orchard.Mvc.Html; 
@using Orchard.Utility.Extensions; 

내가 '가정 것 : 나는 Url.ImageDisplayUrl([ContentItem])를 사용하는데있어 몇 가지 예를보고 있어요,하지만 그 날이 오류를 제공 다음과 같이 'System.Web.Mvc.UrlHelper' has no applicable method named 'ItemDisplayUrl' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.

상단에 내 using 문

은 그걸 가지고 뭔가 빠졌지 만, 무엇을 알아낼 수없는 것 같아. 내가보기를 짓고 있어요 방법은 다음과 같습니다, 나는려고하고있는 URL은 tab.ContentItem.HomepageTab.NavigationItem 떨어져 있습니다 : **

내가 HomepageTab에 대한 클래스 선언이

/** @Model.Items is a collection of my custom content types that were created through the UI **/ 
foreach (var tab in @Model.Items) 
{ 
    var t = new SliderTab 
    { 
     DisplayOrder = tab.ContentItem.HomepageTab.DisplayOrder.Value, 
     ButtonText = tab.ContentItem.HomepageTab.ButtonText.Value, 
     Description = tab.ContentItem.HomepageTab.Description.Value, 
     ImageUrl = tab.ContentItem.HomepageTab.Image.Url, 
     Title = tab.ContentItem.TitlePart.Title, 
     ContentItem = tab.ContentItem, 
     TabText = tab.ContentItem.HomepageTab.TabText.Value 
    }; 

    /** HomepageTab is the custom content type created in the Orchard UI which has a ContentPickerField associated with it. The name on that is NavigationItem, so I just need the friendly URL off of a ContentPickerField's associated ContentItem **/ 
    if (tab.ContentItem.HomepageTab.NavigationItem != null && tab.ContentItem.HomepageTab.NavigationItem.Ids != null) 
    { 
     //this is way, super hacky - getting the actual friendly URL would be better 
     t.NavigateUrl = "/Contents/Item/Display/" + tab.ContentItem.HomepageTab.NavigationItem.Ids[0]; 
    } 

    tabs.Add(t); 
} 

** 편집 맨 위는 ContentItem 속성에서 동적 인 tab.ContentItem.HomepageTag과 상관 관계가 없습니다. 다음과 같이 구성되어 있습니다.

public class HomepageTab 
{ 
    public dynamic DisplayOrder { get; set; } 
    public string ImageUrl { get; set; } 
    public string Title { get; set; } 
    public string Description { get; set; } 
    public string ButtonText { get; set; } 
    public dynamic ContentItem { get; set; } 
    public string TabText { get; set; } 
    public string NavigateUrl { get; set; } 
    public string TabId 
    { 
     get { return "t" + this.DisplayOrder.ToString(); } 
    } 
} 

생각 하시겠습니까?

+0

'foreach (@ Model.Items의 IContent 탭)'할 수 있습니까? 그러면 형식을 컴파일러에 명시 적으로 지정해야하며, 그러면 사용할 확장 방법을 추측 할 수 있습니다. –

+0

시도했지만 'Orchard.ContentManagement.ContentItem'에 'HomepageTab'에 대한 정의가없고 'Orchard.ContentManagement.ContentItem'유형의 첫 번째 인수를 허용하는 확장 메소드 'HomepageTab'이 없습니다. ' – RubyHaus

+0

' tab.As ()' –

답변

1

tab.ContentItem.HomepageTab.NavigationItem은 콘텐츠 항목 선택기 필드이지만이 방법으로 표현하면 동적 개체이므로 컴파일러는 캐스팅하지 않고 사용하려고하면 모든 종류의 혼란을 겪을 수 있습니다. 그래서 처음에는 주조 권하고 싶습니다 :

var pickerField = tab.ContentItem.HomepageTab.NavigationItem as ContentPickerField; 
if (pickerField != null) { 

그런 다음 첫 번째이자 유일한 분야에서 항목을 얻을 수 있습니다 (주의, 우리는 가능성이 아래를 참조하십시오 여기에 선택 N + 1 문제를 일으키는 것) :

var firstItem = pickerField.ContentItems.FirstOrDefault(); 

마지막으로, 우리는 해당 항목의 표시 URL을 요청할 수 있습니다 :

if (firstItem != null) { 
     var url = Url.ItemDisplayUrl(firstItem); 

는 잘 작동합니다. 그러나주의해야합니다 : 위에서 말한 것처럼 각 탭에 대한 항목 모음을 가져 오면 탭 당 하나의 새로운 데이터베이스 쿼리가 실행되어 성능이 저하 될 수 있습니다. 이 문제를 피하기 위해이 게시물에서 설명하는 것과 유사한 기술을 사용하여 관련 콘텐츠 항목을 미리 가져올 수 있습니다. https://weblogs.asp.net/bleroy/speeding-up-pages-with-lots-of-media-content-items

이미지를 미리 가져 오는 대신 처음에 모든 관련 ID (무료입니다. 해당 ID는 이미 보유한 콘텐츠 항목과 함께 저장되어 필드에 저장됩니다). 그런 다음 GetMany을 사용하여 항목에 대한 ID의 로컬 캐시를 작성합니다. 마지막으로 ContentItems 컬렉션 대신 캐시를 사용하여 ID에서 항목을 조회합니다.

나는 이것이 의미가 있기를 바랍니다.

+0

완벽하게, 그것은 내가 필요로했던 정확하게 일했다! 이 인스턴스에서 N + 1 문제에 대해 너무 신경 쓰지는 않습니다. 홈페이지 탭 집합이므로 최대 6 개까지만 가능합니다.하지만이 작업을 수행하면 앞으로 진행할 수 있습니다. 감사!! – RubyHaus