Using KnockoutJS with multiple pages

2020-04-08 11:06发布

I'm just getting started with learning KnockoutJS. One thing that I'm confused about, the samples seemed to all be focused on a single view with a single viewmodel. How do things work with a larger application?

I am going to be writing a pure html/jquery application. All data is served up as json via ajax. There is a common navigation header at the top of the application with multiple tabs and subtabs implemented with Twitter Bootstrap.

If I build each page of the application as a separate html view and js viewmodel, how do I maintain a single unified header? If this was server side asp.net webforms, I would use Master Pages for this. But this is all client side.

Is there something in Knockout that handles this? Or perhaps another library that solves this particular problem?

I suppose I could write the app in one big html page, but it would be rather large. There has to be a better way.

2条回答
混吃等死
2楼-- · 2020-04-08 11:45

You can definately have your viewmodels separate. In the ko.applyBindings method, the first parameter is the viewmodel, but the second optional parameter is the dom element to bind that view model to.

I have not looked closely at Twitter Bootstrap, but I setup jsfiddle that should get you off on the right foot: http://jsfiddle.net/JasonMore/ygT6v/10/

View

<ul id="menu" data-bind="foreach:options">
    <li data-bind="text:option"></li>
</ul>
<br/>
<section id="person"> 
    <p>Hey, <span data-bind="text:fullName"></span>, what are you doing?</p>
    <p><label>First: <input type="text" data-bind="value:firstName" /></label></p>
    <p><label>Last: <input type="text" data-bind="value:lastName" /></label></p>
</section >
<br />
<section id="address"> 
    <p>You live at: <span data-bind="text:fullAddress "></span></p>
</section >

Javascript

// main.js
var menuViewModel = {
    options: ko.observableArray([
        { option: 'person'},
        { option: 'address'}
    ])
};

ko.applyBindings(
    menuViewModel, 
    document.getElementById('menu')
);

// person.js
var personViewModel = new function() {
    var self = this;
    this.firstName = ko.observable('John');
    this.lastName = ko.observable('Doe');
    this.fullName = ko.computed(function() {
        return self.firstName() + ' ' + self.lastName();
    });
};    

ko.applyBindings(
    personViewModel, 
    document.getElementById('person')
);

// address.js
var addressViewModel = new function() {
    var self = this;
    this.address = ko.observable('123 main');
    this.city = ko.observable('Smallville');
    this.state = ko.observable('TX');
    this.zip = ko.observable('12345');
    this.fullAddress = ko.computed(function() {
       return self.address() + ' ' + self.city() + ' ' + self.state() + ' ' + self.zip(); 
    });
};

ko.applyBindings(
    addressViewModel, 
    document.getElementById('address')
);
​
查看更多
三岁会撩人
3楼-- · 2020-04-08 11:58

Are you saying that each tab's content is a "single page"?

If so, you can just use partials to pull the data in using jQuery.load(). Then each page would have its own model, and the header would not be affected, would it? I guess this would need to be clarified.

查看更多
登录 后发表回答