将 requirejs 与 JQuery、jQuery Mobile、Knockout 和 Sammy 结合使用以构建具有外部模板的结构化应用程序时的性能/模板问题 [英] performance / templating issues when using requirejs with JQuery, jQuery Mobile, Knockout and Sammy to build a structured app with External Templates

查看:14
本文介绍了将 requirejs 与 JQuery、jQuery Mobile、Knockout 和 Sammy 结合使用以构建具有外部模板的结构化应用程序时的性能/模板问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个测试应用程序的设置,其中包括 require.js、jQuery、jQueryMobile (jqm)、knockout 和 sammy

require.js 在 jqm、knockout 和 sammy 中加载

在应用程序主页上,我使用 sammy 加载淘汰视图模型.这些 viewModels 在模板中加载..

所以要显示代码...

需要页面:

require.config({jquery: '供应商/jqm/jquery_1.7_min',jqm: '供应商/jqm/jquery.mobile-1.1.0',淘汰赛:'供应商/淘汰赛/淘汰赛-2.2.0',sammy : '供应商/sammy/sammy',文本:'供应商/要求/文本',意见:'../意见',模板:'../模板'}});定义(['应用程序','jqm-config'],函数(应用程序){$(document).ready(function() {console.log("DOM 准备好了");});});

app.js

define(['jquery','knockout', 'sammy','views/home/home', 'views/products/products', 'jqm'],功能($,ko,sammy,appViewModel,productsViewModel){var self = this;self.goHome = function() {ko.applyBindings(new appViewModel());};self.goProducts = function() {ko.applyBindings(new productsViewModel());};萨米(函数(){this.get('#home', function() {self.goHome();});this.get('#products', function() {self.goProducts();});this.get('', function() {self.goHome();});}).跑();});

产品页面

define(['jquery', 'knockout','text!templates/test2.html', 'jqm'],功能($,ko,productsViewTemplate){功能产品类型(ID,名称){var self = this;self.id = id;self.name = 姓名;}返回函数 productsViewModel() {$('body').append(productsViewTemplate);var self = this;self.products = ko.observableArray();var jqxhr = $.getJSON("data/product.json").成功(功能(数据,状态,xhr){self.products.removeAll();$.each(data.data.productTypeList, function(i,item){self.products.push(new ProductType(i, item.longName));})}).error(function() { alert("error"); }).完成(功能(){$.mobile.changePage('#products', { transition: "pop"});});}});

产品 html (text2.html)

<div data-role="header" data-position="fixed"><h1>产品</h1><a href="#home" data-icon="home" data-iconpos="notext" data-direction="reverse">Home</a>

<div data-role="内容"><ul data-role="listview" data-inset="true" data-bind="foreach: products" ><li><a data-bind="attr:{href:'#products/list/' + id}, text: name"></a>

有几个问题

  1. sammy 是否应该按该顺序加载,因为当我刷新它时,它会时不时地抛出一个错误,即由于加载速度太慢而未定义 sammy 或 jquery,我猜

  2. 在产品页面上,如果有人从主页访问它,它会加载正常,因为 jQueryMobile changePage 已被调用,但如果用户随后刷新该页面,来自 JSON 的列表将丢失其所有样式..

我认为这是由于我从模板渲染页面的方式,然后必须列出清单,但我想不出其他方法.

所以我在想(可能不是最佳解决方案)但是有没有办法强制刷新 pageChange?或者有人有更好的解决方案吗?

3.

这是调用外部模板的最佳方法吗/是否有更好的方法将模板附加到正文.我真的认为这样做所花费的时间是导致样式问题的原因,而且当我添加下一个级别的产品时,它会在移至下一个页面之前开始在此页面上呈现它们..

我正在努力寻找使用淘汰赛和 requirejs 加载外部模板的最佳方式.我想将模板保留在 HTML 中,以便团队中的其他人可以轻松地对其进行编辑并提供结构.

这个演示可以在这里看到

http://demo.stg.brightonconsulting.net.au/templates/tests/knockoutJQMProducts/

非常感谢您的帮助

解决方案

看着你的演示,我可以建议一些尝试.

  1. main.js 中移除对jqm-config 的依赖并将其添加到app.js.这样,您将始终确保在 app.js 中的任何内容运行之前设置了 jquery 移动配置.
  2. 确保您的 ko.applyBindings() 调用包含在 .ready() 构造中.
  3. 每次切换页面时,都会将淘汰赛重新绑定到同一个节点.这不是最佳实践,可能会导致一些奇怪的行为.如果您打算这样做,请确保先取消应用绑定.在此处了解如何.

即使修复了所有这些项目,我也不确定您处理事情的方式是否会奏效.您最好预先加载所有 HTML 并将所有页面绑定到一个带有子视图模型的父视图模型.

I have a setup for a test app which includes require.js, jQuery, jQueryMobile (jqm), knockout and sammy

require.js loads in jqm, knockout and sammy

on the app main page i use sammy to load in knockout viewModels. these viewModels the load in the templates..

so to show the code...

require page:

require.config({
    jquery:     'vendor/jqm/jquery_1.7_min',
    jqm:     'vendor/jqm/jquery.mobile-1.1.0', 
    knockout: 'vendor/knockout/knockout-2.2.0',
    sammy : 'vendor/sammy/sammy',
    text:       'vendor/require/text',
views:    '../views',
templates:  '../templates'
}

});

define(['app','jqm-config'], function(app) {
   $(document).ready(function() {
  console.log("DOM IS READY");
});    

});

app.js

define(['jquery','knockout', 'sammy','views/home/home', 'views/products/products', 'jqm'],
function($, ko, sammy, appViewModel, productsViewModel) {

var self = this;
self.goHome = function() {
    ko.applyBindings(new appViewModel());
};

self.goProducts = function() {
    ko.applyBindings(new productsViewModel());
};

 Sammy(function() {
    this.get('#home', function() {
       self.goHome(); 
    });

    this.get('#products', function() {
        self.goProducts();
    });

    this.get('', function() {
       self.goHome(); 
    });

 }).run(); 

});

products page

define(['jquery', 'knockout','text!templates/test2.html', 'jqm'], 
function($, ko, productsViewTemplate){


function ProductType(id, name) {
var self = this;
self.id = id;
self.name = name;
}

return function productsViewModel() {

  $('body').append(productsViewTemplate); 
  var self = this;
  self.products = ko.observableArray(); 

    var jqxhr = $.getJSON("data/product.json")
    .success(function(data, status, xhr) { 
            self.products.removeAll();    
        $.each(data.data.productTypeList, function(i,item){
           self.products.push(new ProductType(i, item.longName));

        })        
      })
     .error(function() { alert("error"); })
     .complete(function() {

         $.mobile.changePage( '#products', { transition: "pop"});

     });

}
});

products html (text2.html)

<div data-role="page" data-theme="c" class="ui-page" id="products">

<div data-role="header" data-position="fixed">
    <h1>Products</h1>
    <a href="#home" data-icon="home" data-iconpos="notext" data-direction="reverse">Home</a>
</div>

<div data-role="content">   
        <ul data-role="listview" data-inset="true"  data-bind="foreach: products" >

          <li>
            <a data-bind="attr:{href:'#products/list/' + id}, text: name"></a>
          </li>


        </ul>

</div>

There are a couple of problems

  1. is sammy supposed to be loaded in that order because every now and again when i refresh it throws an error that sammy or jquery is not defined due too slow loading i am guessing

  2. on the products page if someone goes it from the homepage it loads ok because the jQueryMobile changePage has been called but if a user then refreshes that page the list that has come from the JSON looses all its styling..

I think this is due to the way I render the page from the template and then have to make the list but i cant think of another way of doing it.

so i was thinking (prob not best solution) but is there a way to force a pageChange on a refresh? or has anyone got a better solution?

3.

Is this the best way to call in an external template / is there a better way to append the template to the body. I really think the time its taking to do that is what causing the styling issues and also when i add in the next level of products its starts rendering them on this page before moving to the next..

I am struggling to find the best way to load in external templates with knockout and requirejs. I want to keep the templates in HTML so that others in the team can edit it easily enough and to give a structure.

this demo can be seen here

http://demo.stg.brightonconsulting.net.au/templates/tests/knockoutJQMProducts/

Really appreciate any help

解决方案

Looking at your demo, I can suggest a few things to try.

  1. In main.js remove the dependency on jqm-config and add it to app.js. That way, you will always be guaranteed to have set up your jquery mobile configuration before anything in app.js is run.
  2. Make sure your ko.applyBindings() call is wrapped in a .ready() construct.
  3. Every single time you switch pages, you're re-binding knockout to the same node. That's not best practice and can result in some strange behavior. If you're going to do that, make sure to unapply the bindings first. See how here.

Even with all those items fixed, I'm not sure that the way you're going about things will work. You may be better off loading all the HTML up front and binding all the pages to one parent viewmodel with subviewmodels.

这篇关于将 requirejs 与 JQuery、jQuery Mobile、Knockout 和 Sammy 结合使用以构建具有外部模板的结构化应用程序时的性能/模板问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆