Archief - Knockout.js model relaties

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

GizeH

Legacy Member
Ik ben net begonnen met testen van knockout.js, maar de tutorials op hun site zijn, zoals meestal, simpel, zonder relaties tussen objecten.

Zou iemand mij kunnen zeggen hoe ik het volgende doe in knockout?
Ik heb blogitems en administrators. Ieder blogitem behoort tot 1 administrator.
Hoe kan ik nu aan een blogitem een administrator object koppelen (en tonen in de template)? Ik kan wel een id_administrators veld gebruiken aan het blogitem, maar dit is geen mooie manier.
Is het niet mogelijk om iets in de aard van het volgende te doen?
blogitem.administrator.id ?

HTML:
<ul class="berichten" data-bind="foreach: blogItems, visible: blogItems().length > 0">
            <li>
				<div class="wrapper">                
                	<div class="titelBlok">
	                    <span data-bind="text: administrator.volledigeNaam"></span>
                        <h5 class="titel" data-bind="text: titel"></h5>
                        <a class="delete" href="#" data-bind="click: $root.removeBlogItem">verwijder</a>                  
                    </div>
                    
                    <div data-bind="html: inhoud" class="inhoud"></div>                    
                </div>
            </li>
        </ul>
<script type="text/javascript">
/* <![CDATA[ */
$(document).ready(function() {
	
});

function BlogItem(data) {
	this.id = data.id;
	this.titel = ko.observable(data.titel);
	this.inhoud = ko.observable(data.inhoud);	
	//this.id_administrators = ko.observable(data.id_administrators);
	this.administrator = new Administrator(data.administrator);
	this.comments = ko.observableArray([]);
}

function Comment(data) {
	this.comment = ko.observable(data.comment);
}

function Administrator(data) {
	this.id = data.id;
	this.voornaam = ko.observable(data.voornaam);
	this.naam = ko.observable(data.naam);	
	this.email = ko.observable(data.email);		
	this.volledigeNaam = ko.computed(function() {
		return this.voornaam() + ' ' + this.naam();
	}, this);	
}

/* 
knockout.js nested object
http://jsfiddle.net/8k6pj/3/
*/
function overviewVM() {
	var self = this;
	self.blogItems = ko.observableArray([]);
	self.id = ko.observable();
	self.titel = ko.observable();	
	self.titel = ko.observable();
	self.inhoud = ko.observable();	
	//self.id_administrators = ko.observable();
		
	self.addBlogItem = function() {
		//var blogItem = new BlogItem({ titel: this.titel(), inhoud: this.inhoud(), id_administrators: 1 });
		var admin = new Administrator({'id': 1, 'voornaam': 'davidee' });
		
		var blogItem = new BlogItem({ titel: this.titel(), inhoud: this.inhoud(), administrator: admin  });
		//alert(blogItem.id_administrators());
		$.ajax('/blog/index.php?page=overview&action=addBlogItem',  {
			data: {blogItem: blogItem},
			//data: { titel: 'david' },
			type: 'post',
			success: function(result) {
				//alert(result);
				alert(blogItem.administrator.id());
				self.blogItems.push(blogItem);	
				self.sortOverview();
			},
			error: function(result) {
				//alert(result);
				//alert('error');
			},
		});
	}
		
	self.removeBlogItem = function(blogItem) {
		var blogItem = blogItem;
		//alert(blogItem.administrator);
		//console.log(blogItem.administrator);
		//return false;
		console.log(blogItem);
		
		$.getJSON('/blog/index.php?page=overview&action=delBlogItem', {
			data: {blogItem: blogItem },
			type: 'post',
			success: function(result) {
				//loadOverview();
				//alert(result);
				self.blogItems.destroy(blogItem);
			},
			error: function(result) {
				/*
				alert(result);
				alert('error');
				*/
			},
		});
		
	}
	
	self.blogItems.subscribe(function() {
		//self.sort(sortBlogItems);
		//sortOverview();		
	});
		
	this.loadOverview = function() {
		$.getJSON('/blog/index.php?page=overview&action=overview', function (allData) {
			var mapped = $.map(allData, function(item) {
				console.log(item);
				
				var blogItem = new BlogItem(item);
				blogItem.administrator = item.administrator;
				
				comment = new Comment({ 'comment': 'testcomment' });
				blogItem.comments.push(comment);
				
				return blogItem;
			});
			console.log(mapped);
			
			//mapped.sort(sortBlogItems);		
			self.blogItems(mapped);
			self.sortOverview();
		});		
	}
		
	this.sortOverview = function() {
		this.blogItems.sort(function(left, right) { 
			var aName = left.titel().toLowerCase();
			var bName = right.titel().toLowerCase();
			return aName == bName ? 0 : (aName < bName ? -1 : 1) 
		});
	}
	
	self.loadOverview();
}

//ko.applyBindings(new overviewVM());
var overviewVM = new overviewVM();
ko.applyBindings(overviewVM);
/* ]]> */
</script>

als iemand bekende sites weet die knockout gebruiken (waarvan de code redelijk leesbaar is), post die maar als je wil :) misschien leer ik daar iets bij...

bealzebub

Legacy Member
Je moet het gewoon zelf implementeren. Je doet iets gelijkaardig voor je comments in BlogItem. Je zet dus this.administrator in op iets dat door je administrator objects loopt op zoek naar de juiste id en die dan assignt. Vergeet die dan ook nie observable te maken. Onze code is in coffeescript, maar t komt echt gewoon daarop neer.

Als je een framework met betere model handling wil, ga je best naar iets anders dan Knockout kijken. In Knockout moet je heel veel zelf doen. Het gaat hem echt meer om het MVVM gedeelte (die observables dus die je view met je model syncen) en de rest is up to you.

Ik heb het zelf nog niet gebruikt, maar Ember zou misschien beter zijn. Of als je echt naar een quasi kopie wil van serverside MVC, dan moet je zeker eens BatmanJS bekijken.

Een leuk overzicht van hoe de syntax is moet je zeker hier eens bekijken:
TodoMVC

Scissor

Legacy Member
Ben zelf Knockout tegengekomen in heel het asp.net SPA - gedoe. Daar werd oorspronkelijk geopteerd om uw model handeling door upshot te laten doen, maar upshot is ondertussen wel stilgelegd (vermoed ik, laatste posts zijn van rond maart 2012). Het alternatief dat voorlopig zo'n beetje lijkt door te breken daar is breeze.js. Ben er zelf nog niet mee aan de slag gegaan maar ziet er wel veelbelovend uit.

Zoals hierboven al gezegd is Knockout eerder een tool die je gebruikt om data vanuit je viewmodels in je views terecht te laten komen en te laten syncen. Upshot of Breeze (of andere) zijn dan weer verantwoordelijk voor het effectieve data-verkeer tussen u viewmodels en de server. Denk dat je daar eerder het antwoord moet zoeken.

Ik zou in je Datacontroller een IQueryable maken van je Blogposts en je administrators includen (of omgekeerd) en dan de selectie om te displayen maak je gewoon client-side?

edit: linkje naar breeze: http://www.breezejs.com/

GizeH

Legacy Member
Bedankt voor de reacties, Intussen even breezejs icm angularjs (ipv knockout) aan het testen
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan