How to access template parent context - ractivejs

Assuming the code bellow or something similar to it, how do I pass the parent context in the {{each} context, or how do i access it from the on-click event. Thank you.
<div>
<ul>
{{#each emoticons[emoticons.state.selected].iconList}}
<li on-mouseover="showEmoticonBig" on-click="#this.fire('selectEmoticon',event,this)" class="emoticons-icon">{{{parseToIcons(.code)}}}</li>
{{/each}}
</ul>
</div
ractObj.off("selectEmoticon").on("selectEmoticon", function (event,context) {
});

ractive.fire accepts at least 1 argument - the event name. Everything after that becomes the event arguments. On the other side, on the event handler, it accepts at least 1 argument, the event object that's implicitly provided. Everything after that are the arguments passed by ractive.fire.
In this case, #this.fire will not need event passed in explicitly. It should simply be #this.fire('selectEmoticon',this). This will make context on your handler refer to whatever this was in the call.

Related

How to make a html element show a value after a grpc call(or other async method) with blazor?

I'm testing with blazor and grpc, and I'm trying to follow this tutorial(https://www.youtube.com/watch?v=ynZlJ3pACpI) which seems to be outdated. Either way, with some adaptations it should work, even because there aren't out there many examples or tutorials.
The problem is that the value on the html element is not updated with the grpc response.
I'm supposed to have this:
#page "/greeter"
#inject GrpcService1.GreeterService GreeterService1
#using BlazorApp1.Data
<h1>Grpc Connection</h1>
<input type="text" #bind="#Name" />
<button onclick="#SayHello">Button</button>
<p>#Greetmsg</p>
#code {
string Name;
private string Greetmsg;
async void SayHello()
{
this.Greetmsg = await this.GreeterService1.SayHello(this.Name);
}
}
But something may had been updated because I cannot call the SayHello method that way. I must put the # before the Onclick, otherwise I get the error "Cannot convert method group to no delegate type".
So I put it like this:
<button #onclick="SayHello">Button</button>
This way it works but the result I get from the grpc server only shows up when pressing the button for the next request. I followed the code execution and the request is made, the response comes, but the value on the page isn't updated. Then the code execution ends and still no update. When I press the button for a new request the value somehow is updated.
I also added another button
<button #onclick="SayHello">SayHello</button>
<button #onclick="updateGreetmsg">updateGreetmsg</button>
With an empty function below the other one
public void updateGreetmsg()
{
}
And it is enough to call that function to the earlier received value get shown.
So the await thing is not working in the first function, where it is supposed to.
Anyone knows how to solve this?
It should be async Task SayHello()
Don't use void... use Task instead.
Avoid async void methods
Your button element should be defined as follows:
<button #onclick="#SayHello">SayHello</button>
Note: the onclick attribute is not the normal Html element's onclick attribute. It should be preceded with the '#' sign, and it is called a compiler directive.
Razor components also make extensive use of directive attributes (#onclick, #bind, #ref, and so on) on elements to control various aspects of how components get compiled (event handling, data binding, component & element references, and so on).
Read more...
Note also that after a UI event, such as the above, your component is automatically re-rendered. In the past, we had to call the StateHasChanged method to notify the component that its state has changed, and that it may render. Currently, if you wish to re-render your component due to an alteration of the component's state caused by non UI events, you should call the StateHasChanged method

Meteor - idiomatic way of re rendering template

I have a simple template which has a search box in it:
<template name="search">
<input type="text" name="search" id="search" />
{{> search_results}}
</template>
and obviously, the search results template:
<template name="search_results">
<ul>
{{#each results}}
<li>{{this.resultValue}}</li>
{{/each}}
</ul>
</template>
There is an event for keyp on the search input:
Template.search.events({
'keyup input#search': function (e) {
// fetch result from db
}
});
My problem is, where i have the comment: fetch result from db how do i get the search results template to auto update with the results from the db query?
To be clear: i can get the results fine, just cant see how to get the results template to update.
Essentially, something in the template you want to rerender (search_results) has to be reactive and register a changed event. Out of the box, that means it could be any of the data sources listed here. Since this isn't happening for you, I assume that when you "fetch results from db" you're not actually returning the result of a minimongo query, as this would be reactive by default.
If so, this kind of problem is often most easily solved by rolling your own reactivity using the Deps.Dependency prototype, which (as I understand it) underpins all the other reactive data sources other than the minimongo itself.
If you set var resultsChanged = new Deps.Dependency(), you get an object with two methods: depends and changed. Invoke the former in any computation you want to rerun when it changes and the latter to register a change. Session variables are basically just key/value stores with these Deps.Dependency methods attached to their get and set methods respectively.
So if you have resultsChanged initialised, you just need to make sure your search_results template depends on it, either by adding a new helper function (if results is in the data context as opposed to being a call to a helper), or amending the results helper itself. I'll assume the latter, but adding a new helper instead would be equally trivial.
Template.search_results.helpers({
results: function() {
resultsChanged.depend();
// get your results from wherever
return results;
}
});
That will rerun every time resultsChanged changes, so you just have to add the appropriate code in your callback when you fetch the results:
'keyup input#search': function (e) {
// fetch result from db, passing "resultsChanged.changed()" in a callback
}
Obviously, if the result fetching is synchronous, you don't even need to pass a callback, you can just do it on the next line.
I hope that is vaguely helpful - please let me know if it's not. If my assumption that you're not just pulling something out of the database is wrong, then this is probably on totally the wrong track, so I would recommend posting your actual "fetch result from db" code in your question.

Does Ember have {{itemView}} helper that can be used with {{#collection}}?

Actually, I am looking for methods that let the View be responsible for marking the first or the last item in a collection view, and I found this one How do I add a separator between elements in an {{#each}} loop except after the last element?
.But I don't want to define itemViewClass template's attrs(classNames for example) in javascript, can I just use a {{itemView}} helper or something to define a itemView template?
{{#collection contentBinding="dataList" tagName="ol" classNames="list" itemViewClass="ItemView"}}
{{#itemView classNames="item" classNamesBinding="isLastItem:last"}}
item templates
{{/itemView}}
{{/collection}}
Although, this can be solved in another ways, I just want to know if I can find a built-in support. And I do search for a long time, just can't find Ember.Handlebars.collection's document, it's not in the latest API doc.
starting with the master version of Emberjs, you may try using a custom Handlebars "bound" helper.
it would look something like this :
{{#each item in collection}}
{{#isLastElement item}}
template if last
{{else}}
template if not
{{/isLastElement}}
both templates
{{/each}}
Ember.Handlebars.registerBoundHelper('islastElement',
function(item, options) {
if(functionTellingIfThisIsLastElement(item))
return options.fn(this);
else
return options.inverse(this);
}
);
This is just another way to see things, with functionTellingIfThisIsLastElement either looking in the collection or a property in your item. To access the collection you would have to change some stuffs here, to get the good context + parameters, depending on your code.

Flex - Why is my custom event not being registered with the following event listener?

printableInvoice.addEventListener(batchGenerated, printableInvoice_batchGeneratedHandler);
Results in this error:
1120: Access of undefined property batchGenerated. I have tried it as FlexEvent.batchGenerated and FlashEvent.batchGenerated.
The MetaData and function that dispatches the even in the component printableInvoice is all right. It I instantiate printableInvoice as an mxml component instead of via action-script it well let put a tag into the mxml line: batchGenerated="someFunction()"
Thanks.
batchGenerated should be a string.
It looks like your application dispatches an event whenever the batch is generated.
I'm assuming inside your code you have something along the lines of either:
dispatchEvent( new BatchEvent("batchGenerated") );
or
dispatchEvent( new BatchEvent(BatchEvent.BATCH_GENERATED) );
The second way is usually preferred as using variables instead of magic strings gives you an extra level of compile time checking.
The first required parameter of events is typically the type of the event - Event.CHANGE (aka "change"), FlexEvent.VALUE_COMMIT (aka "valueCommit") etc.
This is what the event listener is actually comparing against.
So in your event listener code above, you would want to change the line to be either:
printableInvoice.addEventListener("batchGenerated", printableInvoice_batchGeneratedHandler);
or hopefully
printableInvoice.addEventListener(BatchEvent.BATCH_GENERATED, printableInvoice_batchGeneratedHandler);
If you want to go further, the Flex documentation goes into some detail as to how the event system works, and how the events are effectively targeted and handled through the use of the Capture, Target, and Bubble phases.

Flex adding event listeners with callback functions which have no arguments

fileReference.addEventListener(Event.COMPLETE, uploadCompleteHandler);
private function uploadCompleteHandler(event:Event):void {}
Above is one way to add an event listener in Actionscript.
By default the callback function needs to have an argument with
name event and type Event.
Is there a way to declare this function without any arguments :
private function uploadCompleteHandler():void {}
Edit : It's possible to add an event handler without any arguments in mxml. So one student wanted to know, why isn't it possible to do the same in actionscript?
The reason is that in mxml what you write isn't actually the handler, is what gets executed in the handler. If you compile with -keep-generated-actionscript flag (To set it in Flex Builder right click to open the project Properties, select Flex Compiler, and add -keep-generated-actionscript to the Additional compiler arguments), you can see in the generated source for your component, that the compiler created a handler for that event, and the body is composed by that you wrote in mxml.
So if you have something like:
click="doSomething();"
You can already notice that you're actually giving an instruction there, that's not a method reference you're passing like when you use addEventHandler.
Then you'll have in the generated file something like:
private function myComponent_Click(evt : MouseEvent) : void
{
doSomething();
}
And somewhere else in the same file the adding of the event listener:
this.addEventListener(MouseEvent.CLICK, myComponent_Click);
Notice the second parameter is not a function result, it's a function reference, because the parenthesizes that denote a function call are missing, and our particular function is not a getter either.
You can also specify more calls in mxml, like:
click="doSomething(); doSomethingElse();"
You can even pass the event parameter to your method:
click="doSomething(event);"
Whatever you write in the value of the mxml event (not sure it's the right term to use) will become the body of the generated handler for the actionscript event.
No, you'll get a runtime exception when the event fires if you'll try to register it as event listener.
You may use the following syntax to allow calling your handler directly without event object:
private function uploadCompleteHandler(event:Event = null):void {}

Resources