Closed nspangler closed 9 years ago
That is an interesting notion. I think we can add a helper to the template being rendered that gives access to $scope. That should give access to any properties on the scope for use in the Meteor template (be it functions or properties). Though I don't have much experience with Meteor templates. Does that make sense?
@netanelgilad I might be wrong but I think @nspangler is trying something much simpler, calling a scope function in a regular angular template (.ng.html). If it is true, then of course it's possible..... @nspangler can you share the code that doesn't work for you please?
@netanelgilad , @Urigo , no what @netanelgilad described is exactly the functionality that I desire. His explanation does make sense on how to achieve it. I am much more of an meteor guy than angular guy so I can assist on the meteor side as much as is needed. I think that providing a helper for the template being rendered is a good solution.
@nspangler I want to work on it now, can you please provide an example code that you would want to use after this feature is added?
@Urigo , @netanelgilad
Say I have a function declared in a controller:
$scope.foo = function (foo) {
console.log(foo);
}
In my meteor template that is included
in the ng.html
that the above controller controls, I can still call the function like so:
Template.meteorTemplate1.events({
'click .logFoo' : function () {
foo("Logged foo");
}
});
where the function foo()
is the function declared in the angular scope.
This might seem like a pointless endeavor to most people, however when I want to integrate my meteor templates with angular/angular-dependencies such as ionic, I need to be able to achieve such functionality. For example instead of having my $scope.foo()
just log, lets replace it with an ionic alert. So that now the click in the meteor template on .logFoo
can display an ionic alert. As of right now without such an enhancement, I set a Session
and have my angular template watch the session for a change. When a change happens and is observed in the $scope
the function fires. Does that make sense? I am more than happy to help in building such functionality.
@nspangler Please try using "controller As" syntax. You can read all about it here: http://toddmotto.com/digging-into-angulars-controller-as-syntax/
But applied to your example, say you have it defined like this:
angular.module('yourModule').controller('yourCtrl', [ '$meteor', function($meteor){
var vm = this;
vm.foo = function (foo) {
console.log(foo);
};
}]);
Then in your view you would have declared somewhere
<div ng-controller="yourCtrl as yc">
...
</div>
And then in the included template you would be able to call the function like this:
Template.meteorTemplate1.events({
'click .logFoo' : function () {
yc.foo("Logged foo");
}
});
Please note yc.
prefix to your function call. (I think there is a missing foo param in the function call)
Note: this is just theory. I haven't tested this, but from what I read about "controller As" syntax, this is exactly the type of thing that would be possible unlike in the classic approach.
Please try this, and let us know.
OK, so the idea is to add a helper to the rendered template. It should be done here and we have easy access to both the template and the scope: https://github.com/Urigo/angular-meteor/blob/master/modules/angular-meteor-template.js#L65-L66
maybe using registerHelper function
@barbatus I wonder what are your thoughts on that
@Urigo yes, that would be very useful for the purpose of integrating standard Meteor packages with angular-meteor. I thought this already existed but I somehow failed to find it in examples. :) So, definitely +1 for this feature from me.
@Urigo As it was mentioned here, I also see ng-controller the only good way to do it.
So we assign any controller into the directive and then, inside of the directive, take controller instance and assign it to, say, $ctrl
property of a template instance. In the events helper we'll be able to use as:
Template.meteorTemplate1.events({
'click .logFoo' : function () {
var $ctrl = Template.instance().$ctrl;
$ctrl.foo("Logged foo");
}
});
@barbatus yes, I wouldn't want to give up on the controller-as syntax.
@nspangler @barbatus @netanelgilad @MilosStanic check this solution and the examples.
It keeps the $scope
updated inside Template.instance().
This is pretty crazy, writing Angular controllers with Blaze templates....
Thanks @stubailo for the help!
After feedback I'll add tests
@Urigo So now it will re-render every time after $apply even if parties is not changed?
@barbatus good point, I'm not sure as I don't know what Blaze is doing if the data it's getting is the same? But also, I haven't found a better way to watch all of the scope and not specific parts of it.
@barbatus ok I've found a solution, check this out: https://github.com/Urigo/angular-meteor/commit/532880b9459c883947457e875802a828e5f3b66d
@Urigo It looks cool but messy, but If it works it's up to you what to do with it ultimately. Potentially another one approach could be to copy scope with angular.copy and then compare prev and new one with angular.equals, not sure though if it works.
@barbatus have you looked at the latest solution in the latest pull request? https://github.com/Urigo/angular-meteor/pull/457
@Urigo ah, you reverted it? Ok, then.
:) yes the getReactively seems like a cleaner solution
Is it possible to directly call an angular function say
$scope.test()
directly from within a meteor template embedded in the angular.ng.html
? Right now I set aSession
in my meteor template and watch theSession
for changes in my.ng.html
. However it seems hacky. Is there a way to achieve this functionality directly?