performance / templating issues when using require

2019-03-01 07:17发布

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

1条回答
相关推荐>>
2楼-- · 2019-03-01 07:37

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.

查看更多
登录 后发表回答