We use Backbone's fetch to get some record from server and add to the page, use create to create record and add to the page, the add to the page part is done by add method cause create and fetch will trigger it, now I want they have diff way to add to the page, created record I want to insert(prepend) to the page and fetched record append to the page, is there good way to do this?
I'm making the assumption that you're using the add -event to listen for when to add the record to the page.
Both the create and fetch methods take an options -object as a parameter. This obejct gets passed around quite a bit and it will end up as the 3rd parameter in your add -event triggers as well.
Now what you can do to differentiate between the add -events from create and fetch, add some variable to your options -object that you can easily recognize. For example
var onAdd = function(model, collection, options) {
if(options.isFetch) console.log('this model was fetched!');
if(options.isCreate) console.log('this model was created!');
}
model.on('add', onAdd);
model.fetch({isFetch: true});
collection.create({foo: "bar"}, {isCreate: true});
There might be some more eloquent way of achieving this by examining the options Backbone internally sets in create and fetch for differences, but this way you'll know for sure.
Related
I have 1 main component. Inside of this component i use WebSockets to receive data from the server. I receive an object with a range of fields inside it. The number of fileds can be from 0 till 10, for example. Each time i receive an object i use forEach() to take all fields. For each field i need to init a component, like this:
self.dcl.loadIntoLocation(StreamComponent, self.elementRef, 'stream');
If a copy of a component for current field of an object already exists, i need to update it with new received data within the view. The main my problem is i don't know how to pass the data from WebSockets to created component. I can create and init it, but i never mind how to pass data to it. Any ideas ?
You could try to leverage the promise returned by the method:
self.dcl.loadIntoLocation(
StreamComponent, self.elementRef, 'stream').then((compRef:ComponentRef) => {
compRef.instance.someAttr = something;
});
This promise allows you to get the instance of the newly created component and set data in its properties (for example, the web socket).
After reading the docs, this is my understanding of sync.
I instantiate some Backbone.Model and call Collection.create(). create() eventually calls sync() and the Model is POSTed to the server. Then there is a sync in the opposite direction such that the Model on the client is given an id.
Does this update then trigger componentDidUpdate()?
Note: componentDidUpdate is a ReactJS thing, so if that doesn't make sense, the question reduces to "Is the client-side model updated and the view re-rendered?"
Since inside of my componentDidUpdate() I am making a call to save() to keep everything up to date, this subsequently makes a call to sync() which then fires a PUT request (because the Model already has an id).
I'm asking, because in my current application, creating a TodoItem seems to result in a POST and then a PUT which I find redundant. Perhaps it is for an unrelated reason.
It actually fires two POSTS and then two PUTS when adding one item, but that is another question.
The first time you save a model (one which doesn't have an id) it will make a POST, thereafter it will make a PUT (update). I think you are confusing when to use create/add/save:
Use save at any point to save the current client collection/model state to the server
Use add to add Model(s) to a collection (a single Model, an array of Models, or an array of objects which contain attributes and let the collection create them)
Use create as a shorthand for creating a model, adding it to the collection, and syncing the collection to the server.
My guess is that you are calling create and save in one operation - you should be using add and save instead, or just create.
The view will not automatically update for you, you will need to listen to changes or events on the collection/model and update the view yourself - there is no equivalent of componentDidUpdate. For example:
initialize: function() {
this.listenTo(this.collection, 'sync', this.onCollectionSync);
},
onCollectionSync: function() {
this.render();
}
First of all I know how to set a LoadingMask for a component but have a problem with the uncoupling of the system I am making so I am just looking for a hint/idea.
I am using a MVVC architecture and in the View I have a Container with several Components in it, one of which is a Grid.Panel. The grid is bound to a store and has an event that when fired calls a method of the store. The following code happens in the ViewController:
functionForEvent() {
var store = getStoreForThisGrid();
store.update(Ext.getBody());
}
What happens now is the update() method makes a request to a server, that updates the store itself and the view component, and I need the loading mask during that time. How I handle the situation right now is I pass Ext.getBody() (or a DOM Element representation of a specific component) to the method and it deals with that reference. This function part of the store that is attached to the Grid and resides in the Store:
update : function (el) {
el.mask();
makeRequest();
el.unmask();
}
What I am looking for is another way (Pattern maybe if such exists for JavaScript) to access the View component from the Store instead of passing it around because that does not seem like a good practice and couples the system.
Since I come from a Java background I would have used the Observer pattern but cannot find how to apply this in JS.
I want my app to fire a method (client side) when a particular subscribed data is changed? for example, the client side has this following subscription
Meteor.subscribe('thePlayers');
thePlayers subscription returns a collection of data which is being displayed in the html through the template.
so whenever the collection get changed, Meteor automatically change the data in the HTML also. Besides this feature, I want my app to fire a method say fire() to be executed as soon as data get changed. What should i do to achieve this?
As David Weldon correctly, cursor.observerChanges is the way to go. Here's how you can use it for your example (assuming your collection is called thePlayers):
client-side
methodCaller = function (methodName) {
return function (/* arguments */) {
Meteor.apply(methodName, arguments)
}
}
var fireCaller = methodCaller('fire')
thePlayers.find().observeChanges({
added: fireCaller,
changed: fireCaller,
removed: fireCaller
})
In case you need this fire() to be run on server, you don't need a method, you can just rely on the observeChanges feature or just observe in your publication. See this question to get an example of how you can achieve that.
In case you need this fire() to be run on client, keep in mind that every helper in your template is reactive, that means it will re-run each time your collection is changed. I assume that it requires that you use the subscription inside it, but that needs to be confirmed.
Perhaps this seems a bit backwards, but I have a view bound with Rivets.js for which I'd like the view to populate the model on initialization.
The usecase is that I'm using server-side rendering to return a snippet (the view) including rivets' data-attributes. So NO JSON is returned from server to client.
Now, by pressing 'edit' a user may put the content in 'edit'-mode, and start editing at will. (Using contenteditable, but this is out of scope here I guess).
So how to make sure the model is populated with values from the view on init?
I know that this question is a little outdated but I recentry tried rivets and I came across the same problem.
The solution:
// In your rivets configuration you disable preload:
rivets.configure({
templateDelimiters: ['[[', ']]'],
preloadData: false
});
// you bind your data
var binding = rivets.bind($('#auction'), {auction: auction});
// you manually publish it once to populate your model with form's data
binding.publish();
And that's it. I still don't know how to disable prelaod per bind
From the example on Rivets website (assign to 'rivetBinding')
var view = rivets.bind($('#auction'), {auction: auction});
doing rivetBinding.publish(); will bootstrap the model with values from the view for all bindings that have 'publishes = true'.
This question is old but it still has no accepted answer, so here goes:
You need to disable the preload configuration so rivets doesn't override whatever is in the input with what you have in your model at the time you do the binding. This can be done via the preloadData=false configuration, either globally (rivets.configure(...)) or view-scoped (third param to rivets.bind(...)).
After the binding, you need to publish the view (pull the values to your model). You also need to set up the observers via sync() call, otherwise your binded methods won't be triggered.
Using the same example as the previous answers:
var view = rivets.bind($('#auction'), { auction: auction }, {
preloadData: false
});
view.publish();
view.sync();