【问题标题】:Mustache - dynamically load partial view and render (springboot app)Mustache - 动态加载局部视图和渲染(springboot 应用程序)
【发布时间】:2014-11-21 11:41:50
【问题描述】:

我有一个带有 Mustache 的 spring-boot-starter-web。

我有一个用户登录页面,验证凭据后,我会打开包含用户详细信息的部分视图,我的代码如下所示:

//Javascript

function AjaxNoAsyncPOST(urlString, dataObj) {
    return $.ajax({
        headers: {
            "X-Token": token
        },
        type: "POST",
        async: false,
        url: urlString,
        processData: false,
        data: JSON.stringify(dataObj),
        contentType: "application/json; charset=utf-8",
        success: function (data) {
            return true;
        },
        failure: function (errMsg) {
            $(".signupAlert").html("<span style='color: red; display: block; padding-bottom: 5px;'>Please contact the system administrator.</span>");
            return false;
        },
        error: function (errMsg) {
            $(".signupAlert").html("<span style='color: red; display: block; padding-bottom: 5px;'>The username or password you entered is incorrect.</span>");
            return false;
        }
    });
}

function validateLoginForm(loginForm) {
    var loginForm = $(loginForm);
    var dataArray = loginForm.serializeArray(),
        len = dataArray.length,
        dataObj = {};

    if (validateLoginData(dataObj)) {
        var urlString = contextName + 'api/login/token';

        var user = AjaxNoAsyncPOST(urlString, dataObj).responseJSON;

        if (Object.prototype.toString.call(user) == '[object Object]') {
        //The user object is of the following JSON format
        //  var user = {
        //          "user": [
        //              {"name": "London"},
        //              {"token": "Paris"},
        //              {"role": ["USER", "ADMIN"]},
        //              {"isAdmin": true}
        //          ]
        //      },


            showDiv('homebox');

            //get a reference to our HTML template

            var userInSessionTemplate = $('#userInSessionTemplate').html();


            console.log("Before template="+userInSessionTemplate); //blank

            //tell Mustache.js to iterate through the JSON and insert the data into the HTML template
            var output = Mustache.to_html(userInSessionTemplate, userData); //I have tried to user Mustache.render, but no success

            console.log("output="+output); //blank
            console.log("After template="+userInSessionTemplate); //blank

            //append the HTML template to the DOM
            $('#userSessionData').append(output);//empty
        }
    }
}

我的 index.html

<!-- this is the HTML template -->
<div id="homebox" style="display:none; "
     class="mainbox overviewbox col-sm-8 col-sm-offset-2">
        {{>overviewPartial}}
</div>

我的overviewPartial.html

<div class="container">
    <div class="navbar navbar-default" role="navigation">
        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse navbar-ex1-collapse">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#"><i class="icon-home icon-white"></i>Overview</a></li>
            </ul>

            <script id="userInSessionTemplate" type="text/template">

                    <ul class="nav navbar-nav navbar-right">
                        <li class="dropdown">
                            {{#user}}
                            <a href="#" class="dropdown-toggle" data-toggle="dropdown">Welcome, {{name}} <b
                                    class="caret"></b></a>
                            {{/user}}
                            <ul class="dropdown-menu">
                                <li><a href="/user/preferences"><i class="icon-cog"></i> Preferences</a></li>
                                <li><a href="/help/support"><i class="icon-envelope"></i> Contact Support</a></li>
                                <li class="divider"></li>
                                <li><a href="/auth/logout"><i class="icon-off"></i> Logout</a></li>
                            </ul>

                        </li>
                    </ul>

            </script>
        </div>
        <!-- /.navbar-collapse -->
    </div>
</div>

我正在尝试呈现用户详细信息,但我无法这样做。有人可以帮我解决这个问题吗?

更新 1:我对overviewPartial.html进行了更改,现在我得到了模板详细信息,但是当我打印$('#userInSessionTemplate').html()时,似乎我{{user}} 已经被评估,所以我没有得到用户标签之间的 html

更新 2:overviewPartial.html 包含一个部分

     {{#user}}
      <a href="#" class="dropdown-toggle" data-toggle="dropdown">Welcome, {{name}} 
<b class="caret"></b></a>
  {{/user}}

在我得到响应和对象后,这部分总是空的,我似乎找不到什么问题。它不会打印 Welcome Victor。

用户对象

Object { token="6psobJJaZvpo1UMyxbyzUIXs...aQLcvCzSADGciNJ7wNFHsvH", name="Victor", roles=["ROLE_API", "ROLE_ADMIN"], isAdmin=true}

更新 3:输出包含:

<ul class="nav navbar-nav navbar-right" style="border: 1px solid black; height: 50px; width: 50%">
                    <li class="dropdown">

                        <ul class="dropdown-menu">
                            <li><a href="/user/preferences"><i class="icon-cog"></i> Preferences</a></li>
                            <li><a href="/help/support"><i class="icon-envelope"></i> Contact Support</a></li>
                            <li class="divider"></li>
                            <li><a href="/auth/logout"><i class="icon-off"></i> Logout</a></li>
                        </ul>

                    </li>
                </ul>

更新 4:我想我找到了问题,问题是 ViewResolver。看起来是这样的

@Bean
public ViewResolver getViewResolver(ResourceLoader resourceLoader){
    MustacheViewResolver mustacheViewResolver = new MustacheViewResolver();
    mustacheViewResolver.setPrefix("/WEB-INF/views/");
    mustacheViewResolver.setSuffix(".html");
    mustacheViewResolver.setCache(false);
    mustacheViewResolver.setContentType("text/html;charset=utf-8");

    JMustacheTemplateLoader mustacheTemplateLoader = new JMustacheTemplateLoader();
    mustacheTemplateLoader.setResourceLoader(resourceLoader);

    JMustacheTemplateFactory mustacheTemplateFactory = new JMustacheTemplateFactory();
    mustacheTemplateFactory.setTemplateLoader(mustacheTemplateLoader);

    Mustache.Compiler compiler = Mustache.compiler();

    mustacheTemplateFactory.setCompiler(compiler);

    mustacheViewResolver.setTemplateFactory(mustacheTemplateFactory);

    return mustacheViewResolver;
}

而我的 index.html 包含

<div id="homebox" style="display:none; "
     class="mainbox overviewbox col-sm-8 col-sm-offset-2">
        {{> overviewPartial}}
</div>

现在我得到一个错误:

java.lang.UnsupportedOperationException: Template loading not configured
at com.samskivert.mustache.Mustache$1.getTemplate(Mustache.java:788) ~[jmustache-1.9.jar:na]
at com.samskivert.mustache.Mustache$IncludedTemplateSegment.execute(Mustache.java:663) ~[jmustache-1.9.jar:na]
at com.samskivert.mustache.Template.executeSegs(Template.java:92) ~[jmustache-1.9.jar:na]

不知道我错过了什么

【问题讨论】:

  • 首先指向, 之后的var user 会破坏代码。第二点,将你的代码拆分成更小的函数;它将使它更容易理解、更小(某些部分是可重复使用的)并且更容易修复错误。
  • @user3536548,我已经更新了代码,第二个var用户只是解释AJAX响应时的格式是什么。小部分看不懂,你觉得哪个文件或函数太大了,请告诉我,我会尽量分解。
  • 您是否也知道您的函数validateLoginData 是递归的?它在if (validateLoginData(dataObj)) { 上调用自己,这永远不会返回,因为它会不断地在dataObj 上调用自己,这只是一个空对象。不管怎样,我一直在让你的代码更独立,再给我一点时间,需要了解你的validateLoginForm函数

标签: jquery spring-boot mustache


【解决方案1】:

我通过将相关代码移动到单独的函数中,重新编写了您的代码以分离关注点。

现在您的关注点已经分开,应该更容易理解和调试,即将模板呈现到屏幕上的代码与获取和验证数据的代码是分开的。

也就是说代码还没有完成,你将不得不这样做,因为我不知道你试图在你的 validateLoginForm 函数的第一个 if 语句中检查什么,但它应该至少现在更容易了。

function ajaxRequestNoSync(dataobject){
    jquery.each(['url','token'], function (i,toCheck) {
        if(dataobject[toCheck] == 'undefined'){
            throw (toCheck + ' needs to be defined')
        }
    })

    return $.ajax({
        headers: {
            'X-Token' : dataobject.token
        },
        type: dataobject.type || 'GET',
        async: false,
        url: dataobject.url
        processData: false,
        data: getData(dataobject.data),
        contentType: "application/json; charset=urft-8",
        sucess: results,
        failure: results,
        error: results,
    })
}

function getData (data) {
    return null if data == 'undefined'
    return JSON.stringify(data)
}

//determins if results are error or not by checking type of third arg, which would be a string only on failure or error
function results(first,status,third){
    if(third.typeof == 'string'){ 
        flash(third)
        return false
    }else{
        return true
    }
} 

function flash (message){ //flashes the error message on screen
    var element = $(".signupAlert")
        element.html(message)
                    .addClass('errorclass') //change to error css class
        setTimeout(function(){
            element.fadeOut(1000)//fades out over 1 second
            setTimeout(function () {element.html('')},1000)//erases elements html content after it has faded away
        },5000)//will make message faseout after 5 seconds
}

function validateLoginForm(loginForm){
    var form = {}
    form.dataSerial = $(loginForm).serialzeArray()
    form.dataLength = form.dataSerial.length
    form.data = {}

    if(){ //check for somthing here, not quite sure what though
        var urlString = contextName + 'api/login/token'
        var user = ajaxRequestNoSync({
            'url':urlString,
            'data': form.dataSerial,
            'type':'POST',
            'token': token //not sure what the token is or where it comes from
        }).responseJSON

        if(user.typeof == 'object'){
            renderResult(user)
        }
    }
}

function renderResult(userData){
    showDiv('homebox');
    var userInSessionTemplate = $('#userInSessionTemplate').html();
    var output = Mustache.to_html(userInSessionTemplate, userData);
    $('#userSessionData').append(output)
}

【讨论】:

  • 感谢您的帮助,我正在调查这个问题,但现在下周会回复。
  • 我使用您的代码并运行应用程序只是为了回到我遇到的相同问题。我已经用我需要的内容更新了这个问题。
  • 你修复if(){ //check for somthing here, not quite sure what though ajax 请求后user 的内容是什么?
  • 是的,我添加了所有缺少的信息并删除了来自服务器的令牌(某种会话变量)。打算用用户对象更新票证,但忘记了;没有更新相同。我还注意到,当我使用 console.log(userInSessionTemplate) 时,我没有得到用户标签之间的代码,就像它已经被评估过一样。
  • 老实说,这超出了我的知识范围,所以很抱歉,我无法提供更多帮助。
猜你喜欢
  • 2012-05-18
  • 1970-01-01
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多