问题
I have a SPA using knockout JS for data binding and sammy for routing. I have a deck of cards that I am trying to have a dynamic routing to. My problem is that it doesn't work when I try to set a knockout observable from the routing function in sammy.
My HTML, where I try to bind the name of the deck, looks like this:
<!-- Create Deck -->
<div id="createDeck" class="page" style="display:none;">
<input type="text" class="form-control" placeholder="Untitled Deck..." data-bind="value: $root.deck.name" />
</div>
<script type="text/javascript" src="lib/jquery-1.9.1.js"></script>
<script type="text/javascript" src="lib/knockout-2.3.0.js"></script>
<script type="text/javascript" src="lib/bootstrap.min.js"></script>
<script type="text/javascript" src="lib/sammy.js"></script>
<script type="text/javascript" src="js/Models/Deck.js"></script>
<script type="text/javascript" src="js/Models/Card.js"></script>
<script type="text/javascript" src="js/ViewModels/DeckViewModel.js"></script>
<script type="text/javascript" src="js/ViewModels/CardViewModel.js"></script>
<script type="text/javascript" src="js/routing.js"></script>
The Deck.js and DeckViewModel.js looks like below
function Deck(deckid, name, cards) {
var self = this;
self.id = deckid;
self.name = name;
self.cards = cards;
}
function DeckViewModel(deck, cards) {
var self = this;
self.deck = ko.observable(deck);
self.cards = ko.observableArray(cards);
self.goToCard = function (card) { location.hash = card.deckid + '/' + card.id };
}
// Bind
var element = $('#createDeck')[0];
var deckView = new DeckViewModel(null, null);
ko.applyBindings(deckView, element);
Finally, in my routing I try to create a new Deck, like this:
// Client-side routes
(function ($) {
var app = $.sammy('#content', function () {
this.get('#deck/:id', function (context) {
showPage("createDeck", ": Create Deck");
console.log(this.params.id);
deckView.deck = new Deck(1, "test", null);
console.log(deckView.deck);
});
});
$(function () {
app.run('#/');
});
})(jQuery);
function showPage(pageID, subHeader) {
// Hide all pages
$(".page").hide();
// Show the given page
$("#" + pageID).show();
// change the sub header
$("#subHeader").text(subHeader);
}
As you can see, I'm trying to create a test deck with the name 'test', but the binding <input type="text" class="form-control" placeholder="Untitled Deck..." data-bind="value: $root.deck.name" />
seems to bind the letter 'c'.
I'm at a loss, please help.
I tried to make a jsfiddle to demonstrate my problem
回答1:
In your code the value assignment is not correct unless you are using Knockout-es5 plugin. here is the correct code
var app = $.sammy('#content', function () {
this.get('#deck/:id', function (context) {
showPage("createDeck", ": Create Deck");
console.log(this.params.id);
deckView.deck(new Deck(1, "test", null));
console.log(deckView.deck());
});
});
回答2:
The way I've done this before is to define my Sammy() routes within the ViewModel. Shorter example for brevity:
(function($) {
function ViewModel() {
var self = this;
self.deckId = ko.observable(null);
Sammy(function() {
this.get('#/deck/:deckId', function(context) {
self.deckId(this.params.deckId);
});
});
}
$(function() {
ko.applyBindings(new ViewModel());
});
})(jQuery);
That way you can access your observables, etc, via self.
来源:https://stackoverflow.com/questions/19149129/setting-a-knockout-observable-using-sammy-for-routing