I know this goes against knockout but I've gotten to a point where I'd like to create a control and bind an observable to it. I'll know the field in which it will be bound to but not the model. I'm wondering if there is a way to find which observable is bound to the text or value of an element? I have a complex view model and the class that the observable could be bound to could be 3 layers deep. I can get the context back by using:
ko.contextFor(this)
but that brings back the entire model, I'd like to just get back the observable. Any suggestions?
I got it figured out! For some reason the issue was because I was using a hidden field. I changed the field to a text box and made it invisible and all started working.
Related
I want to create an example of a table with dynamic data that also indicates when a table value has changed.
So imagine a table of data. One cell on one row changes it's value and it turns green to show that it has changed.
I'm new to Angular. I've been through the tutorial but I'm struggling to figure out the right kind of approach to this. I'm not asking for a step by step tutorial, but if an Angular veteran could give me a broad-strokes approach as to which parts of Angular I need to be focusing on, and a few tips on how best to structure the app, it would be a big help.
Right now I have an array of JSON objects attached to $scope.rows and a table with the rows created using ng-repeat. There's a button that changes some values in the rows data at random. That seems to be doing the trick of updating the rows as I expected, but I haven't figured out how to bridge that gap between data-binding and dom manipulation. And it's possible that my approach is all wrong.
You need to detect when your rows object changes and which element changed. I have done something similar by first creating a copy of your rows object then putting a watch on scope.rows (make sure you include the object equality flag). When the watch fires, loop through the scope.rows object and when you find the element that is different, put some boolean property on it and set it to true.
In your row DOM tag, use:
ng-class="{highlightRowCSSClass:row.boolProp, normalRowCSSClass:!row.boolProp }"
and set the highlightRowCSSClass to be whatever you want to indicate a changed element.
After you set the prop on the object, set the copy of the rows to what it currently is and wait for the watch to fire again. You will need to clear the old value off each element when you loop through it again so you don't have two elements that are "on".
I am having a form, which comprises of several textboxes and one button.
I am using the Kendo UI MVVM format. How shall I get the value of each textbox and store it in an object on click of the button?
Will I have to use normal jQuery in order to get the values or is there some other way of getting the values from each of them?
Thanks
Hardik
Please take a look at these documentation pages:
http://demos.kendoui.com/web/mvvm/index.html
http://docs.kendoui.com/getting-started/framework/mvvm/observableobject
http://docs.kendoui.com/tutorials/mvvm-in-kendo-ui
These pages contain answers to most of the questions you'll have concerning Kendo UI MVVM. It would be silly and presumptuous of me to think that I could explain it better than the qualified and hard working individuals at Telerik that have so painstakingly compiled these documentation pages.
The gist of it is that you need to create an instance of the kendo.data.ObservableObject that has properties for the values you are working with. This is your view-model. Then in your markup for your text boxes, include values for the data-bind attribute that reference the properties in your observable object. Create a function in your view-model to handle the button's click event. Put a data-bind attribute in your button that binds the click event to your function. Finally, call kendo.bind(<element>, <observable object>), and that will connect the wires from your markup to your view-model object.
In your click event-handler, you can take the values of the view-model, and insert them into the object you need. You should not need to use "normal jQuery" for anything besides referencing the element to call bind on.
Quickly you can retrieve the value this way using JQuery:
$('#yourTextBoxID').data('kendoMaskedTextBox').value();
you can use this code:
$('#yourTextBoxID').val();
I recently found and applied the changeTracker/dirtyFlag approach successfully in my code and everything was good. Very neat and useful. Though, today, I was trying to use it again and something weird was happening: the somethingHasChanged trigger was firing as soon as I opened the page.
I looked, searched and nothing. I was not doing any change to the observables after setting the tracker.
After a couple of hours of this, I found the root of the problem:
One of the observables is binded to a <select> element thus setting the currently selected <option>.
If I remove this binding, it no long triggers.
I don't know why this happens, since the value is only read (supposedly).
Any thoughts on this?
My guess would be that you are binding against numeric values and the selected one is being written back to your view model as a string, as KO reads it out of the DOM element.
First here's a plunk: http://plnkr.co/edit/2gD0AB. This plunk doesn't seem to work correctly because $scope.$on("$viewContentLoaded") won't fire, but on my machine it works just fine and I hope you get the idea.
What I'm trying to do there is simply move field objects from $scope.fields to $scope.groupFields = [], $scope.listFields = [], $scope.dataFields = [] when dragging them to the appropriate droppable areas. I've manager to do this using jQuery UI and jQuery UI touch punch (just to be mobile safe).
If you drag an element from the fields box to the one of the empty boxes you'll notice nothing happens on the screen besides the field elements hanging around where you left them. But if do a console.log($scope.fields) in the drop event listener you'll notice that all of the field objects are correctly set inside each of the field boxes.
If you click the Add element button then you'll simply trigger console.log($scope.groupFields); and suddenly all the elements appear correctly in their corresponding boxes like intended in the first place.
After pulling my brains out and after searching the internet for some time I found out that $scope.$apply(), called in the drop event after the moveField function, actually fixes my issue.
And I don't understand why. Shouldn't there be a digest already running and updating the view based on what I'm doing in the controller?
Thanks!
Just because the code that handles these jQuery drop events is inside the controller, it doesn't mean it will run under the angularjs scope/word. For those changes to make effect, you will need to force the angularjs app to do a dirty checking on its models. That can be accomplished by calling $apply() or $digest() methods. You should always call one of these methods after handling an jQuery event that changes $scope properties or after a timeout (or interval).
Ok getting frustrated on this one.... Using knockoutJS to do some visual interaction stuff.
What I have is a button that is going to make an AJAX call to validate some data. That call sends back a CanProceed property as well as an object that represents other view settings. The code works when I set CanProceed(true) this turns on a DIV that has more DIVs inside it, each of those visibility properties are bound to a Permissions.AllowXXX that is set from the server.
See the fiddle for an example
http://jsfiddle.net/RcCAx/
What I want to have happen is when I get the Permissions from the server I should be able to tell knockout about the object and have the page UI update but its not working. If I declare the observable first (like with the CanProceed property) it works, but if I try and use the ko.mapping.fromJS(serverdataobject) here its not updating stuff that was bound to it earlier.
Help......
See updated fiddle for a solution. The key here is to have Permissions be an observable