-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Need way to reactively depend on data context / template arguments #2010
Comments
Very important. If this were possible, we wouldn't need to write no-op helpers to carry out certain actions using reactivity as we are forced to now. Such helpers are problematic because 1) they are a hack that has no purpose being in the template, and 2) can't access the template instance anyway. |
Consider more distinction between a Template class, a Template instance, First, instead of 'this' in a Template instance helper being simply Data Context perhaps we could initialize the instance 'this' properties in the Template.created / instantiated / init function.
|
I just have no idea how to initialize/reinitialize a custom widget . Let say I have <template name="uploader">
<input id="{{_id}}"
type="hidden" />
</template> ...and I want to initialize it like this: whateverWidget("#" + _id); I want to reinitialize the widget when It doesn’t work in Template.uploader._id = function () {
var _id = this._id;
setTimeout(function () {
whateverWidget("#" + _id)
}, 10);
return _id;
} ...but I think it’s not a good idea. Does this issue cover my case? |
as a workaround maybe this will work var mutationsObserver = function (targetNodes, callback){
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var myObserver = new MutationObserver (mutationHandler);
var obsConfig = { childList: true, characterData: true, attributes: true, subtree: true };
targetNodes.each ( function () {
myObserver.observe (this, obsConfig);
} );
function mutationHandler (mutationRecords) {
console.info ("mutationHandler:");
callback();
}
}
Template.someTemplate.rendered = function (){
mutationsObserver($("#target"), function (){
doSomthing();
})
} |
@artpolikarpov good point, I actually use @timtch although a reasonable workaround, that is going way outside of the Meteor API and probably introducing unnecessary complexity; it probably would not make sense to depend on this in core Meteor code - I'm guessing we will still need to come up with a good way to do this in a more straightforward way. |
@mizzao the observer should be disconnected() on destroyed. In my case it works |
+1 @timtch ; maybe some sugar could make it more palatable. |
Some suggestions: Emit an event on an element when it's updated. Example:
In a
Make accessing the template data reactive, like it's own local session. Example:
I ran into a problem related to the above, I had a template like so:
JS:
I don't know if you can guess, but when |
@charlesjshort typo i guess |
I think this could be easily solved by simply making data reactive. You could use defineProperty to make getter a function which records a dependency. Because this is on the server side you do not have to worry of Other approach would be to simply change API from BTW, if we are changing this, why would not |
@mitar Not sure what you are talking about about the server side; I think this is all client side. I think it would actually be really helpful to be able to access template instances (somehow) from helpers, especially given some of the current limitations in how we can use inputs reactively. Of course, if we are able to get fully reactive inputs in |
Oh, my bad. I do not know how I confused this. :-( Yes, also accessing template instance in helpers is needed. There is a ticket #1529 for this. |
dat spam, please write the right person ... 2014-04-08 20:09 GMT+02:00 Mitar notifications@github.com:
|
Ok, I am not going to pretend to know as much as everyone on here, but I have been trying to solve this issue for over a week since updating to Meteor 0.8.0. I have put together a small little repo as best I know how to describe the problem that I am having related to this issue. Basically outside of using a setTimeout I am unable to use jQuery to affect the data being loaded into the DOM. https://github.com/yankeyhotel/meteor-rendered-test2 In my mind I do think something like a callback for when the data is accessible in the Template would be good. I started noticing this issue when I had the same x-editable problem @davidworkman9 had on Issue #2001. Hopefully this helps someone else and informs the team on how people are using it. If I've got anything wrong just let me know. Still kinda new at all this and just trying to keep up. Thanks again. |
+1 - would welcome a
Therein, AND while I say that...I realize it's not ideal: if I have an @timtch's use of the MutationObserver is really interesting too... |
+1 for We have a lot of code which is based on old Template.rendered semantics. Porting it to 0.8 would be a real pain without Template.updated. |
Personally, I think I would be happy with a Template.destroy() method, that caused the whole rendered process to happen again the next time the template was instantiated. |
+1 for I'm running into problems much like @yankeyhotel and @DenisGorbachev, and would prefer not to depend on workarounds such as @timtch has put together...only to have to replace when the proper "Meteor way" is finally introduced. Hopefully, that didn't come across as whiney. I plan to try the MutationObserver workaround on one or two of my current issues, so appreciate the comment @timtch. |
I think the easiest workaround for now would be to send a custom jQuery object whenever data changes. So you have a dummy template helper which sends an event you listen to in a listener you attach in created and detach in destroyed. |
@mitar one of the solutions I gave above was pretty much that:
Except you don't need to turn off the event on |
If we went that way, it'd be nice if there was some extra info that came along with it, for example:
|
@davidworkman9: Yes, but I am proposing that one can implement this for a workaround in meantime. I do not think that official solution should involve events because Meteor does not really use them anywhere. But for a workaround is good enough. |
@mitar, I see. The more I think about this I like the idea of an emitted event, you could even define it in the event map. A |
The good question is why we would need both |
Simple: |
But does this difference warrant a new callback? You can know yourself it you are called first time or nth time. If you need to know that, you keep a counter. |
Correct me if I don't understand the inner workings of Blaze, but the whole ideas is that |
What I am suggesting is that maybe |
(With different semantics, that it is not called when rerendering happens, which now does not happen anymore, but when data changes. So more like: rerender if you have something custom, here is new data.) |
@mitar Yes, we definitely need to let you know when the data context changes. That is what this issue is about. For everyone else, please refrain from talking about an |
Another issue, related to this,, seems to be that the I'm really looking forward to the next iteration of blaze. EDIT: Workaround for this is to grab the updated data directly from the element. Template.foo.rendered = ->
$(@firstNode).popover
html: true
placement: "auto right"
trigger: "hover"
container: @firstNode
content: =>
# FIXME: Workaround as popover doesn't update with changed data
# https://github.com/meteor/meteor/issues/2010#issuecomment-40532280
UI.toHTML Template.bar.extend data: UI.getElementData(@firstNode) |
The folks at React have thought through a lot of the issues in making a reactive DOM extensible for third-party components. I'd be surprised if Blaze ends up needing significantly fewer events than theirs: http://facebook.github.io/react/docs/component-specs.html |
@mizzao I mentioned that exact problem above where I suggested that |
@davidworkman9 it's the replacement for the old I think a reactive |
Is there any update on this? |
@mitar there is a ton of stuff in Meteor 0.8.3. Specifically, |
and @dgreensp, we can close this issue now, no? Or is there still something not addressed? I know all my needs have been met :) |
Hm, what is difference between |
MDG will correct me if I'm wrong, but it looks like it's being phased out. The Blaze-like functions seem to only be in the |
I'm currently working on merging |
+1 for UI being an alias of Blaze and not being hardcoded as the API. |
Great new about the new reactive context Blaze.getCurrentData() in combination with the autorun of view! Thanks a lot! One more question: Do you need to stop the autorun on views or are they automatically stopped when the view is being destroyed? |
Autoruns on Views are automatically stopped when the View is destroyed. On Monday, September 1, 2014, Pieter Soudan notifications@github.com
|
ok, nice. |
Yup, the computation is returned. On Monday, September 1, 2014, Pieter Soudan notifications@github.com
|
Sorry, I wasn't clear. I know they are being returned (as with every autorun), but I wondered if you could access all the view computation instances from other lifecycle callbacks (without manually registering them). Something like This can come in handy when you want to stop all view computations manually and rerun them later on (when the view is being hidden, but not destroyed for instance) |
No, you'll need to keep track of the Computation objects yourself in this case. |
Does getCurrentData allow any filtering on certain attributes somehow? |
Thanks! Using Template.watchVideo.rendered = ->
@autorun( () ->
video = Template.currentData();
$( "wistia_#{video.wistia_id}" ).empty()
wistiaEmbed = Wistia.embed( "#{video.wistia_id}", videoFoam: true )
) IMO the docs could be a little more verbose on the utility of these functions. |
Closing now that we have |
As part of a template, you often want to respond reactively to changes in the input (i.e. the arguments / the data context of the template). For example, you want to kick off a CSS animation when some text changes, or you want to feed an argument into a jQuery plugin.
Currently, compiled templates get under-the-hood reactive access to the data context, and lifecycle callbacks get non-reactive access (
this.data
). There should be a way to get reactive access to the data context in cases where you can't just hard-code the source (e.g. a Session variable).Based on discussion in #2001.
The text was updated successfully, but these errors were encountered: