如何在 Razor 语法中的两个不同列表之间交替

本文关键字:两个 列表 之间 Razor 语法 | 更新日期: 2023-09-27 18:36:37

我在这个上面画了一个空白。我有两个正在创建div的foreach循环,我正在尝试从第二个foreach中获取1或两个项目,以显示第一个foreach的每2个项目。这是代码..

@foreach (var stream in Model.LiveStreams)
{
    <div id="divLiveStream" class="well-livestream well-sm">
       <div class="row">
          <div class="col-md-2">
              <div class="ui-icon-image">
                  <img src="~/Images/placeholder.jpg" width="100%" />
              </div>
          </div>
          <div class="col-md-10">
              <div class="text-left row">
                  <div class="col-md-12">
                         @stream.UserName
                  </div>
                  <div class="col-md-12">
                         @stream.Status
                   </div>
              </div>
          </div>
       </div>
    </div>
}
@foreach (var post in Model.LivePosts)
{
   <div id="divLivePost" class="well-liveposts well-sm">
     <div class="row">
          <div class="col-md-2">
              <div class="ui-icon-image">
                  <img src="~/Images/placeholder.jpg" width="100%" />
              </div>
          </div>
          <div class="col-md-10">
              <div class="text-left row">
                  <div class="col-md-12">
                       @post.AspNetUser.UserName
                  </div>
                  <div class="col-md-12">
                       @post.PostDescription
                  </div>
              </div>
         </div>
     </div>
  </div>
}

因此,为了进一步澄清,我尝试显示 2 个divLiveStreams,然后显示 2 个divLivePost,并继续使用该模式。我是MVC的新手,所以我不确定该怎么做,我在这个星期五画了各种各样的空白。提前感谢!

编辑:这是我的观点模型。

public class LiveStreamViewModel
{
    public IEnumerable<LiveStream> LiveStreams { get; set; }
    public IEnumerable<tPost> LivePosts { get; set; }
}

编辑:可能是一个愚蠢的问题,但我使用我的控制器返回模型。在我拥有如下所示的控制器之前,我应该如何调用您在控制器中创建的新 ViewModel?这是我的控制器。

public ActionResult LiveStream()
{
    Service service = new Service();
    LiveStreamViewModel model = new LiveStreamViewModel
    {
        LiveStreams = service.GetLiveStream(),
        LivePosts = service.GetLivePosts()
    };
    if (TempData["Message"] != null) ViewBag.Message = TempData["Message"]; ViewBag.Header = "Success!";
     return View(model);
    }
}

还有我的数据服务。

public IEnumerable<LiveStream> GetLiveStream()
{
    using (dboMyJeepTraderEntities context = new dboMyJeepTraderEntities())
    {
        return (from s in context.tStatusUpdates select new LiveStream 
        { 
            Status = s.Status,
            UserName = s.AspNetUser.UserName
        }).ToList();
    }
}
public IEnumerable<tPost> GetLivePosts()
{
    return (from p in _context.tPosts select p).ToList();
}

如何在 Razor 语法中的两个不同列表之间交替

您需要一个视图模型,交替发生视图模型的水

public abstract class AbstractThing
{
    public abstract string TheUserName { get; }
    public abstract string TheDescription { get; }
}
public class LivePost : AbstractThing
{
    public string UserName { get; set; }
    public string PostDescription { get; set; }
    public override string TheUserName
    {
        get { return this.UserName; }
    }
    public override string TheDescription
    {
        get { return this.PostDescription; }
    }
}

public class LiveStream : AbstractThing
{
    public string UserName { get; set; }
    public string Status { get; set; }
    public override string TheUserName
    {
        get { return this.UserName; }
    }
    public override string TheDescription
    {
        get { return this.Status; }
    }
}

public class AlternatingThingsViewModel
{
    public ICollection<AbstractThing> AbstractThings { get; private set; }
    public AlternatingThingsViewModel(ICollection<LivePost> lps, ICollection<LiveStream> lss)
    {
        this.AbstractThings = new List<AbstractThing>();
        /* this is not correct...here is where you would "two by two" add items to the this.AbstractThings in the order you want.  the key is to have one collection exposed by the viewmodel */
        if (null != lps)
        {
            foreach (AbstractThing at in lps)
            {
                this.AbstractThings.Add(at);
            }
        }
        if (null != lss)
        {
            foreach (AbstractThing at in lss)
            {
                this.AbstractThings.Add(at);
            }
        }
    }
}

现在,您循环访问单个集合

@foreach (var post in Model.AbstractThings)
{
   <div id="divLivePost" class="well-liveposts well-sm">
     <div class="row">
          <div class="col-md-2">
              <div class="ui-icon-image">
                  <img src="~/Images/placeholder.jpg" width="100%" />
              </div>
          </div>
          <div class="col-md-10">
              <div class="text-left row">
                  <div class="col-md-12">
                       @post.TheUserName
                  </div>
                  <div class="col-md-12">
                       @post.TheDescription
                  </div>
              </div>
         </div>
     </div>
  </div>
}

下面是一个"一个然后另一个"的实现...只要 LivePost 计数大于 LiveStream。 并且没有错误检查。 但给你一个想法。

public class AlternatingThingsViewModel
{
    public ICollection<AbstractThing> AbstractThings { get; private set; }
    public AlternatingThingsViewModel(ICollection<LivePost> lps, ICollection<LiveStream> lss)
    {
        this.AbstractThings = new List<AbstractThing>();
        /* this is a "one by one" with no error checking if the counts are different */
        IEnumerator<AbstractThing> livePostEnum = null == lps ? null : lps.GetEnumerator();
        IEnumerator<AbstractThing> liveStreamEnum = null == lss ? null : lss.GetEnumerator();
        if (null != liveStreamEnum)
        {
            liveStreamEnum.MoveNext();
        }
        if (null != livePostEnum)
        {
            while (livePostEnum.MoveNext() == true)
            {
                AbstractThing lpCurrent = livePostEnum.Current;
                AbstractThing lsCurrent = null == liveStreamEnum ? null : liveStreamEnum.Current;
                if (null != liveStreamEnum)
                {
                    liveStreamEnum.MoveNext();
                }
                this.AbstractThings.Add(lpCurrent);
                if (null != lsCurrent)
                {
                    this.AbstractThings.Add(lsCurrent);
                }
            }
        }
    }
}

和一些调用代码。

    static void Main(string[] args)
    {
        try
        {
            ICollection<LivePost> lps = new List<LivePost>();
            lps.Add(new LivePost() { UserName = "LivePostUserName1", PostDescription = "LivePostDescription1" });
            lps.Add(new LivePost() { UserName = "LivePostUserName2", PostDescription = "LivePostDescription2" });
            lps.Add(new LivePost() { UserName = "LivePostUserName3", PostDescription = "LivePostDescription3" });
            lps.Add(new LivePost() { UserName = "LivePostUserName4", PostDescription = "LivePostDescription4" });
            ICollection<LiveStream> lss = new List<LiveStream>();
            lss.Add(new LiveStream() { UserName = "LiveStreamUserName1", Status = "LiveStreamStatus1" });
            lss.Add(new LiveStream() { UserName = "LiveStreamUserName2", Status = "LiveStreamStatus2" });
            //lss.Add(new LiveStream() { UserName = "LiveStreamUserName3", Status = "LiveStreamStatus3" });

            AlternatingThingsViewModel atmv = new AlternatingThingsViewModel(lps, lss);
            int modCheckCount = 0;
            foreach (AbstractThing at in atmv.AbstractThings)
            {
                Console.WriteLine("{0}, {1}", at.TheUserName, at.TheDescription);
                if (++modCheckCount % 2 == 0)
                {
                    Console.WriteLine("");
                }
            }

嗯,所以 - 是的 - 在Controller这样做显然是有道理的。但是,话又说回来,Razor 只是(大部分)C#,所以无论你在一个中做什么,你都可以在另一个中做:

@{
    var streamIndex = 0;
    var postIndex = 0;
}
@while (streamIndex < Model.LiveStreams.Count() || postIndex < Model.LivePosts.Count()) {
    @foreach (var stream in Model.LiveStreams.Skip(streamIndex).Take(2)) {
       // html code
       streamIndex++;
    }
    @foreach (var post in Model.LivePosts.Skip(postIndex).Take(2)) {
       // html code
       postIndex++;
    }
}