I have a store where I want to set a filter in the beforequery event.
The problem is when I do it like this
store.addFilter({property:'name', value: 'xxx'});
the actuall addFilter call will send a request, which is a problem because it will fire the beforequery event again.
So I add the supresevent parameter to the function call
store.addFilter({property:'name', value: 'xxx'}, true);
but, in this case the request doesn't have the filter param at all.
Am I missing something ?
All I want to is to add a filter in a beforequery event and the let it do a request
There's a property on the store called autoFilter. Set it to false. It's a private property, therefore it's not in the doc.
I've been struggling with a problem in a similar context. I wanted to set a filter upon the store using the setFilter() method. But using this method I had encountered that the store triggered the load event twice. One request included the filter parameters, the other one didn't.
Request1:
Request2:
This behavior resulted in wrong information in my component. After a while of tinkering I encountered that I can bypass the setFilter() method by invoking the filter() method of the store directly.
Grid-Code:
...
initComponent: function () {
var me = this;
me.callParent(arguments);
me.getStore().filter([
{
property: someProperty,
value: someValue
}
]);
},
...
Applying the filter this way has solved the issue for me. I hope this will help you as well.
Related
I have to use valueHasMutated method in ko to fire subscription on page load while binding Country list dropdown so that I can fetch state on the basis of selected dropdown, is there an alternative to this ? How can I fire the country subscription without using this method ?
Country List: <select id="CountryDropdownList" data-bind="options: viewModel.CountryCollection,optionsText:'CountryName',optionsValue:'CountryName',value:viewModel.SelectedCountry"></select>
State List: <select id="StateDropdownList" data-bind="options: viewModel.StateCollection,optionsText:'StateName',optionsValue:'StateName',value:viewModel.SelectedState"></select>
<script>
var viewModel = ko.mapping.fromJS(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)));
console.log(viewModel.SelectedState()); //State3 the initial value
viewModel.SelectedCountry.subscribe(function (newSelectedCountry) {
alert(newSelectedCountry);
console.log(viewModel.SelectedState()); //undefined why?
$.ajax({
url: 'Home/GetStateList?Country=' + newSelectedCountry,
success: function (data) {
viewModel.StateCollection(ko.mapping.fromJS(data)());
console.log(viewModel.SelectedState()); //state0 why?
}
})
});
ko.applyBindings(viewModel);
$(function () {
//to fire subscription
viewModel.SelectedCountry.valueHasMutated();
})
</script>
Don't specify viewmodel.on your bind variables in the HTML. When you call ko.applyBindings, it creates the default context for your bind variables.
If the values of the value bound variable doesn't match any of the options values, it will (by default) be set to undefined. This may be what is happening (see your "undefined why?" comment). Try adding the valueAllowUnset option. I'm probably explaining this wrong. But you'll want to check the initial values against the options, at any rate.
I guess that the problem is in attaching the event handler after the complete construction of the model object by calling fromJS.
All observables do already have their values set, so the subscribed function is not called without the manual call to valueHasMutated.
A solution could be by
first creating the model, including the subscribe to the SelectedCountry observable.
instantiate this model and set the observable values
This way the subscribed function will be called, because the handler is attached before values are set.
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.
Apologies if this has been asked before, I have searched but I'm finding it very hard to express my problem in a search friendly way. And I can't figure it out from the knockout documentation, however it seems like a basic question.
I have 3 select lists and a Knockout view model. Selecting a value in the first list updates an observable in the view model. I then need to make an ajax post, sending that value to the server and retrieving a list of values which I put in an observable array in the view model, which will in turn update the other 2 lists.
I'm happy with wiring up to observables and that part is working fine, my question is how and where to trigger the ajax call.
If I trigger it on the change event of the first select it seems to cause a race condition which means it sometimes gets called before the view model has updated. I could trigger it without using the observable, but that doesn't seem very knockoutish.
If I use a custom binding for retrieving values it will cause the ajax call to be made twice and I can't put the retrieval in a function because it needs to run asynchronously (and it would be called twice).
I feel like I need something which listens to an observable and triggers an ajax call without any visual element.
Any help would be gratefully received.
Triggering things that should happen in response to view model changes generally works through subscriptions in knockout.
function ViewModel() {
var self = this;
self.someValue = ko.observable();
self.otherValue = ko.observable();
self.someValue.subscribe(function (newValue) {
// do something with newValue, like an Ajax request.
// assuming jQuery
$.get("your/url", {val: newValue})
.done(function (data) {
self.otherValue(data);
})
.fail(function () {
alert("could not retrieve value from server");
});
});
}
In my controller I am storing data as $scope.$parent.dossierSummaries = data;
but after log out and login the application $scope.$parent.dossierSummaries retains the same old data.
I am doing this on log out
.success( function( response, status ) {
if ( response.status > 0 ) {
var u = $rootScope.user.username;
$cookieStore.remove('myapp');
$rootScope.user = { username: '', role: 0 };
success(u);
}
else {
error(response.messages);
}
})
.error( function( response, status ) {
error(['There was an error logging you out.']);
});
in angularJS, you shouldn't set the variable directly to a controller but you should retrieve it from a service instead. So whenever you load a controller you should write a init() function to get value of that model. So everytime you will have the correct data from server.
Code example and docs : http://docs.angularjs.org/guide/dev_guide.services.creating_services
Another approach to manually tracking and cleaning things up would be to broadcast a 'logout' event on the rootScope (or other custom event). Then listen for the event either in your controller or in your service to clean up the data.
Broadcast:
$rootScope.broadcast('logout');
Watching for an event (in a service for example):
$rootScope.on('logout',function(){
dossiers = [];
});
I don't think there is any effective way to achieve it. Any object (controller, directive,filter or as a matter of fact any js object) can hold reference to another object (in your case user), and one cannot determine easily who all are holding reference.
The reference would only get release if you do it either explicitly or when the object holder the reference is destroyed.
What you can try is
$rootScope.user.username='';
$rootScope.role=0;
Assuming some object are tracking this specific object the data would be cleared now.
if you don't mind a slight screen flickering on logout, you can refresh the page using a method like this:
$window.location.replace($window.location.toString().split('#')[0]);
this would clear out all the $scope and $rootScope variables, and in my case has solved the issue.
If you want to clear the $scope, I think you can use it's constructor method or proto (prototype), which is used in constructor. I believe you can do that to reset the scope to initial state. If someone knows any more on this, feel free to comment.
The title of the question pretty much sums it up, I'd like my view to respond differently to a model instances initial save vs any future saves. Right now I'm grabbing the model's isNew attr before I save and then triggering a custom event, but I was wondering if there was anything built in?
Checking model.isNew() is the built-in way of telling whether the initial save has happened yet. If checking isNew is working for you, keep on doing it.
The initial save should issue an ID for the object, so you could bind a function to "change:id" and it would execute after the initial save succeeds. Or you could add logic to the "success" and "error" callbacks of create().
With help from this answer, I came up with the following solution:
var originalSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
console.log(method);
originalSync.apply(Backbone, [method, model, options]);
};
I can now check what method is being called.