My EditView is:
//.addChild(
EditView::new().fixed_width(30).with_name("customer_names")
//)
Now when try set content:
siv.call_on_name("customer_names", |view: &mut EditView| {
view.set_content("helloooo");
});
Does nothing. :<
However, the textviews work well! 🙈
let view = siv.find_name::<TextView>("customer_id").unwrap();
view.set_content("this is ok helloo!!");
Thanks in advance!
I found the problem.
It didn't work because of the order of calling the functions. This is the creation of the editview:
EditView::new().fixed_width(30).with_name("customer_names") //no work
The search by name function was not finding the view. If I do so, if it finds the view:
EditView::new().with_name("customer_names").fixed_width(30) //this work ok!!
I have to put the with_name() first before other properties, otherwise it puts a wrapper on it and the editview doesn't work.
Related
I am trying to implement ForEach.onMove using Core Data. I have two entities, Parent with a To-Many relationship to Child, with the relationship marked as Ordered. The view is something like this:
struct ParentView : View {
#ObservedObject var parent : Parent
var body : some View {
List {
ForEach($parent.children! as! [Child]) { child in
ChildView(child)
}.onMove {
parent.managedObjectContext!.performAndWait { indices, to in
(parent.children! as! NSMutableOrderedSet).moveObjects(at: indices, to: to)
try! parent.managedObjectContext!.save()
parent.objectWillChange.send()
}
}
}
}
}
Results are:
No errors of any kind.
During debug of the onMove function, I can see that the items are re-ordered as required
The managedObjectContext.updatedObjects is empty at the same debug step, before the call to save()
When reloading the app, the re-ordering is obviously not saved (apparently because the updatedObjects set was empty at #3.)
What am I doing wrong? How can I make the MOC realize the re-ordering change?
I fixed this, apparently with a simple solution. I am posting this for future generations of google searchers. :D
The problem is with this line:
(parent.children! as! NSMutableOrderedSet).moveObjects(at: indices, to: to)
Apparently, taking the immutable version and making it mutable works, but doesn't update the managed object. This works:
parent.mutableOrderedSetValue(forKey: "children").moveObjects(at: indices, to: to)
I have a function which uses Anko's async in order to call Google's Distance API and get the distance from one location to another. unfortunately i don't know how to get the data from inside the async and pass it to another function. the code looks something like this
fun getDistance(location1:LatLng,location2:LatLng){
async{
val result = URL(url).readtext()
uithread{
//Parser
//distance value
}
}
}
I'd like to also mention im really new to kotlin or android development in general, please be kind.
There are a number of ways to tackle this; pass an object to the function with your array in it that gets rearranged in your function, or go with something like:
fun getDistance(location1 : LatLng, location2 : LatLng, f: (Long) -> Unit){
doAsync{ // Anko is deprecated as I have been made aware
val result = URL(url).readtext()
val distance : Long = // parse result
uiThread{
f(distance)
}
}
}
and call that with
getDistance(loc1, loc2) { toast("The found distance was $it") }
This is by no means the only way to go; you could update a larger-scoped variable, call a listener, put your lat-longs in a class with updating functions that are called, or a bunch of other ways that I am too lazy to think about :)
I copied the code from kraken. I don't understand why there is a space between get and app(). Can someone please explain what's going on here?
var kraken = {
get app() {
return this._app;
},
use: function (route, delegate) {
//.....
}
}
No, in javascript a function cannot contain spaces. The code you are showing is using the get keyword to bind a property to a object.
get
Binds an object property to a function that will be called when that property is looked up.
Have a look to getters and setters in javascript.
It's a getter.
Check out this link.
The function is get and it's exposing a property called app.
UPDATE
I have to apologize for confusing the readers. After I got totally lost in the code, I reverted all my changes from Mercurial repo, carefully applied the same logic as before -- and it worked. The answers below helped me understand the (new to me) concept better, and for that I gave them upvotes.
Bottom line: if a call to a missing method happens within a closure, and resolution set to DELEGATE_FIRST, methodMissing() will be called on the delegate. If it doesn't -- check you own code, there is a typo somewhere.
Thanks a lot!
Edit:
OK, now that you've clarified what your are doing (somewhat ;--))
Another approach (one that I use for DSLs) is to parse your closure group to map via a ClosureToMap utility like this:
// converts given closure to map method => value pairs (1-d, if you need nested, ask)
class ClosureToMap {
Map map = [:]
ClosureToMap(Closure c) {
c.delegate = this
c.resolveStrategy = Closure.DELEGATE_FIRST
c.each{"$it"()}
}
def methodMissing(String name, args) {
if(!args.size()) return
map[name] = args[0]
}
def propertyMissing(String name) { name }
}
// Pass your closure to the utility and access the generated map
Map map = new ClosureToMap(your-closure-here)?.map
Now you can iterate through the map, perhaps adding methods to applicable MCL instance. For example, some of my domains have dynamic finders like:
def finders = {
userStatusPaid = { Boolean active = true->
eq {
active "$active"
paid true
}
}
}
I create a map using the ClosureToMap utility, and then iterate through, adding map keys (methods, like "userStatus") and values (in this case, closure "eq") to domain instance MCL, delegating the closure to our ORM, like so:
def injectFinders(Object instance) {
if(instance.hasProperty('finders')) {
Map m = ClosureToMap.new(instance.finders).map
m?.each{ String method, Closure cl->
cl.delegate = instance.orm
cl.resolveStrategy = Closure.DELEGATE_FIRST
instance.orm.metaClass."$method" = cl
}
}
}
In this way in controller scope I can do, say:
def actives = Orders.userStatusPaid()
and "eq" closure will delegate to the ORM and not domain Orders where an MME would occur.
Play around with it, hopefully I've given you some ideas for how to solve the problem. In Groovy, if you can't do it one way, try another ;--)
Good luck!
Original:
Your missingMethod is defined on string metaclass; in order for it to be invoked, you need "someString".foo()
If you simply call foo() by itself within your closure it will fail, regardless of delegation strategy used; i.e. if you don't use the (String) delegate, good luck. Case in point, do "".foo() and it works.
I don't fully understand the issue either, why will you not have access to the closure's delegate? You are setting the closure's delegate and will invoke the closure, which means you will have access to the delegate within the closure itself (and can just delegate.foo())
nope, you will not catch a missing method and redirect it to the delegate with metaclass magic.
the closure delegate is the chance to capture those calls and adapt them to the backing domain.
that means...
you should create your own delegate with the methods required by the dsl.
do not try to force a class to do delegate work if it's not designed for the task, or the code will get really messy in not time.
keep everything dsl related in a set of specially designed delegate classes and everything will suddenly become ridiculously simple and clear.
I have a variable Object foo, which is not null. I want to use foo.bar, but only if it won't bomb me with 'No such property: bar for class: Whatever'.
How should I do the following test:
if (/*test-here*/) {
use(foo.bar)
}
Use object.hasProperty(propertyName). This will return a truthy value (the property reference) if the property exists. Also object.metaClass.hasProperty(instance, propertyName) is possible. Use object.respondsTo(methodName) to test for method existence.
I do this in my Gradle scripts:
if(project.hasProperty("propertyThatMightExist")){
use(propertyThatMightExist)
}
If you're doing it on lots of foos and bars you could write (once, but before foo is created):
Object.metaClass.getPropertySafe =
{ delegate.hasProperty(it)?.getProperty(delegate) }
Then you can write:
foo.getPropertySafe('bar')
This worked for me :
Customer.metaClass.properties.find{it.name == 'propertyName'}.
Customer in this example is a domain class. Not sure if it will work for a plain Groovy class
boolean exist = Person.metaClass.properties.any{it.name == 'propName'}
if propName is an attribute ,exist=true // vice versa
I can't speak for Groovy specifically, but in just about every dynamic language I've ever used the idiomatic way of doing this is to just do it, and catch the exception if it gets thrown, and in the exception handler do whatever you need to do to handle the situation sensibly.