在Html之前没有调用JavaScript

时间:2016-07-19 23:46:43

标签: javascript html razor

我的标题中有一个脚本,它调用了一个应该填充视图模型的web api。这是在下面。

@using GigHub.Controllers
@using GigHub.ViewModel
@model GigHub.ViewModel.ProjectsViewModel
@{
ViewBag.Title = "Projects";
}

<head>
<script>
    (function getProjects() {
        $.get("/api/projects")
            .done(function () {
                alert("Got Projects");
            })
            .fail(function () {
                alert("Something failed!");
            });
    });

</script>
</head>

然后我的html将循环遍历viewModel并在整个html中设置它,但每次运行时,它都会为每个中的Model.ProjectList抛出一个空引用异常,因为它没有填充然而。我认为将脚本放在标题中会让它先运行,但情况似乎并非如此。

<h2>Projects</h2>

<ul class="gigs voffset4" style="width: 600px;">

    @foreach (var project in Model.ProjectList)
{
    <li>
        <div class="date">
            <div class="month">
                @project.Name
            </div>
            <div class="day">
                @project.Key
            </div>
        </div>
        <div class="details">
            <span class="artist">
                    @project.Id
                </span>
            <span class="genre">
                    @project.ProjectTypeKey
                </span>
        </div>
    </li>
}

</ul>

这是我的实际projectsController

 public class ProjectsController : Controller
{

    private readonly string m_Username = Properties.Settings.Default.username;
    private readonly string m_Password = Properties.Settings.Default.password;

    public ActionResult Index()
    {          
        var client = new RestClient("https://example.net/rest/api/2/");
        client.Authenticator = new HttpBasicAuthenticator(m_Username, m_Password);

        var request = new RestRequest("project/", Method.GET);
        request.RequestFormat = DataFormat.Json;

        request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };

        var response = client.Execute<List<Project>>(request);
        var content = response.Content; // raw content as string

        if (content == null)
            throw new Exception(response.ErrorMessage);

        var projectArray = JsonConvert.DeserializeObject<List<Project>>(response.Content);

        var viewModel = new ProjectsViewModel()
        {
            ProjectList = projectArray,              
            Heading = "Projects"
        };

        return View("Projects", viewModel);
    }
}

1 个答案:

答案 0 :(得分:1)

您正在尝试将javascript和C#代码混合在一起并期望它能够正常运行!不,它没有那种方式。

视图中的c#代码(foreach块)由服务器中的razor执行,生成的html标记将发送到客户端浏览器。这意味着,如果您在视图中访问Model.ProjectList,则应确保使用该属性(ProjectList)将模型传递到视图。

您有2个选项。

1。完整的服务器端方法

在get动作中,创建视图模型的对象,设置ProjectList属性并将其发送到视图。

public ActionResult Index()
{
  var vm = new YourViewModel();
  vm.ProjectList= GetListOfProjectsFromSomeWhere();
  return View(vm);
}
private List<ProjectItem> GetListOfProjectsFromSomeWhere()
{
  var list=new List<ProjectItem>();
  list.Add(new ProjectItem { Name="Project 1"}); // Replace with real data here
  return list;
}

假设您有一个名为YourViewModel的视图模型,如下所示

public class ProjectItem
{
  public string Name {set;get;}
}
public class YourViewModel
{
   public List<ProjectItem> ProjectList {set;get;}
}

和 并确保您的剃刀视图强烈键入此视图模型

@model YourViewModel
<h2>Projects</h2>
@foreach (var project in Model.ProjectList)
{
  <p>@project.Name</p>
} 

2。使用ajax加载页面内容。

从客户端代码,调用api(就像你做的那样)并解析响应并更新DOM。

您需要在视图中创建一个容器元素,以便您的javascript代码可以将项目附加到api调用结果中。

<ul id="projects"></ul>

现在确保您的javscript代码将在文档就绪事件上执行。

function getProjects() {
    $.get("/api/projects")
        .done(function (data) {
            var projectHtml="";
            $.each(data,function(i,item){
               projectHtml+="<li>"+item.Name+"-"+item.Key+"</li>";
            });
            $("#projects").html(projectHtml);
        })
        .fail(function () {
            alert("Something failed!");
        });
}
$(function(){
    getProjects();    
});

假设您的api调用返回一个项目数组,每个项目都包含Name&amp; Key这样的属性

[{Name:"Project1", Key:"Pr1"},{Name:"Project2", Key:"Pr2"}]