Issue structuring JavaScript (separation of view and model logic)
I'm working on a Javascript-heavy piece (using jQuery) for a website (at the moment, I'm working on getting a prototype going).
To summarize what I'm doing, I have a series of 'icons'. Each icon, at the moment, is an image. I also have a series of 'buckets'. The icons all start in a single bucket. The user is able to create new buckets and drag the icons around from bucket to bucket. The icons can also be turned on and off by clicking on them (although they still remain in their buck开发者_运维技巧et).
I have it all working fine at the moment, however at the moment it's basically a bunch of img elements getting moved around from div to div. When I'm ready to start implementing the server-side logic, I'm going to need a way to communicate what's going on to the server.
What I need is a 'model' object reflecting what's going on with the view. It'd be good if when the user is ready to send the data back to the server, I'd have an object I could serialize representing what I need. For example, if the user has dragged the email.png icon into bucket the Options bucket, I would like for this to be reflected in a model object (i.e. { 'options': ['email'] }).
The issue is, all my logic is occurring based on events. When the user drags the icon to a div, an event is fired on the img DOM element, from which I'm not sure how to access it's model to update it. The only thing I can think of is parsing the img src and use that to find out the name of the model option but that's a very hackish and inelegant solution.
Any ideas?
You could maintain a raw object model or graph of objects by attaching a root object to something in the DOM, or alternatively using the jQuery data system to keep it in.
Even reference your UI DOM elements into this centralized model to help reduce the complexity of two distinct models.
It's not uncommon for jQuery plugins to centralize state in the manner you seek, inside the jQuery data system.
raw JavaScript
document['myObjectGraph'] = {
first: 1,
second: 'two,
images: [
document.getElementById('img1'),
document.getElementById('img2')
],
items: [
'a',
'b',
another = { /* building out the model...*/ };
]
};
or jQuery data system (same idea)
jQuery.data(document.body, 'myObjectGraph', {
first: 1,
second: 'two,
images: [
$('#img1'),
$('#img2')
],
items: [
'a',
'b',
another = { /* building out the model...*/ };
]
});
Effectively this creates a manageable model in one place (that you choose the design of) - it represents the state of your icons, buckets and anything else; it can be serialized using JSON and sent to the server through an ajax call; and your UI elements can even be rebuilt/refreshed from it.
This idea comes with the cost of extra indirection and effort of keeping synchronized the raw model with the UI model.
Can you use the element's id or class attribute to store the the name of the model? Then you can specify whatever string you want for each instead of trying to go off the src attribute.
You could just leave the icons in the buckets and then ask the buckets what's in them when you need to talk to the server. As long as the icons have some unique attribute (such as id
) to identify them then you could build your model on the fly as needed. Something like this could be used to serialize your buckets:
http://jsfiddle.net/ambiguous/3ufhn/
That will work nicely as long as things stay simple. If things get more complicated then an explicit MVC setup would make things easier and John K's .data
approach would come in handy; you could also use a <form>
with hidden inputs to track your state.
精彩评论