I have an external library (http://support.video.limelight.com/support/docs/player_api/) that calls the function limelightPlayerCallback() every time something with the player changes.
I want to be able to trigger actions in my Angular controller every time the library calls that function. When I declare the function in my HTML, everything works as expected.
function limelightPlayerCallback (playerId, eventName, data){
console.log(playerId);
console.log(eventName);
console.log(data);
}
Gets me
player1
onPlayerLoad
null
And also allows me to access the LimelightPlayer object and run queries and commands on it like.
LimelightPlayer.doGetPlayheadPositionInMilliseconds()
LimelightPlayer.doLoadMedia()
But once I start trying to declare the limelightPlayerCallback() function in my controller, or access the LimelightPlayer object, the function is never called so I am not able to interact with the player at all.
What is the best way to go about interfacing with a library that works like this in Angular?
Related
I'm creating a location-based chat app in Meteor. Now I want to render only the chat messages which are in the users region. The TheRegion.region variable gets filled with an HTML5 geolocation request.
Template.locationchat.helpers({
messages: function () {
return Messages.find({location: TheRegion.region});
}
});
The problem of this code is that the TheRegion.region variable is still null when this helper is called. Is there a way to run the helper in a callback of the geolocation function? Or run the template helper when the variable has a value?
I often find in Meteor that if you are waiting on a variable all you need is an if clause to protect yourself.
Try this:
Template.locationchat.helpers({
messages: function () {
if(TheRegion.region)
return Messages.find({location: TheRegion.region});
}
});
It doesn't feel natural, but usually it works. Give it a try.
That's because your variable isn't reactive.
In your onCreated:
TheRegion = new ReactiveDict();
TheRegion.set('region',undefined);
Now, region is always going to exist by the time it reaches the helper & when the value changes, your helper will rerun.
I'm trying to implement communication between my view models in a knockoutjs driven application. I scaffolded it using yeoman tool, and as you can see it uses AMD:
define(['knockout', 'signals', 'text!./nav-bar.html'], function(ko, Signal, template) {
function NavBarViewModel(params) {
this.route = params.route;
}
return { viewModel: NavBarViewModel, template: template };
});
I have to define an object that I would later use to dispatch events, right? Something like that:
var EventDispatcher = {
itemClicked: new Signal()
};
And then, whenever something happens in the NavBarViewModel I'd like to do:
EventDispatcher.itemClicked.dispatch();
The problem is - where should I put this EventDispatcher thing? It's obvious that it should be some kind of a global object, so that every VM could get a hold on it, but it would be ugly. Dependency injection came to mind, since everything else in this architecture I choose is done this way, but how to achieve that? I come from WPF, MVVM world, and so far I've used MVVMLight framework which had this great Messenger component. Is there anything like that in the JS world (and if it's js-signals lib I'm already using, then how should I use it to achieve my goal?)
I could also use the subscribable object built into the knockout fw, but the question still stands - where to put it (or how to share the instance between VMs)?
You'd quite simply inject it by including it in your define.
First, create a new file, EventDispatcher.js with your EventDispatcher code inside (and other relevant Knockout bits, like returning the view model and whatnot).
Then in your current file add it in:
define([ ... , ... , "EventDispatcher"], function( ... , ... , EventDispatcher )
Now you can simply call its methods within this file by using:
EventDispatcher.itemClicked.dispatch()
(Where EventDispatcher is what we've named it in our define parameters).
Do bear in mind though that your EventDispatcher.js file will also need the signals file passed to it through its own define wrapper.
I am using marionette in my application. I am showing ItemView through regions like in the following.
var productInfoViewObj=new productInfoView.ProductInfoView({model:tagInformationModel.tagInformationModelObj});
exports.MyApp.bodyContainer.show(productInfoViewObj);
This is the code, I written inside view.
exports.ProductInfoView=Backbone.Marionette.ItemView.extend({
domInfo:{
mainTemplateId:"tagProductListTpl",
tableTemplateId:"taginfoViewTpl",
tableContentDiv:"taginfoViewDiv",
//tad Info
tagInfoTabId:"tagInfoBtn",
productInfoTabId:"productInfoBtn"
},
template:function(){
return commonFunctions.templateCompilation("tagProductListTpl","");
},
onRender:function(){
console.log(document.getElementById("productInfoBtn"));
}
});
I am passing templateId and data as arguments to commonFunctions.templateCompilation. It will compile and return compiled string. That compiled result passing to template.
As per my assumption, after completion of template, onRender function will trigger. What I mean before onRender, dom will available whatever we are templating using template.
But I am getting null inside onRender function.
I want a callback, it should trigger after template available in dom. so I can access elements whatever I templated using template.
I can do one thing, whatever I written inside onRender, I can setup time like in the following way.
onRender:function(){
setTimeout(function(){console.log(document.getElementById("productInfoBtn"));},1000);
}
If I set time, working fine but it's not correct way to implement.
can anyone help me.
Thanks.
It's resolved, I have to use onShow instead of onRender function. Now it's working fine.
// Main class
function App() {
this.task = new Task(this); // pass the instance of this class to Task so
// it has access to doSomething
}
App.prototype.doSomething = function () {
alert("I do something that Task() needs to be able to do!");
};
function Task(app) {
// This class needs access to App()'s doSomething method
this.appInstance = app;
this.appInstance.doSomething(); // Great, now Task can call the method
}
var app = new App();
The aim of the code above is to give Task access to one of App's methods called doSomething. The code is the current way I'd go about it and I'm posting this to see if it's the best way...
To give Task access I simply pass the whole instance of App, is this efficient or is there a better way to go about it? Is the code above general practice in going about doing something like this?
Yes, what you have is fine. It is a circular dependency, however because of JavaScript's dynamic nature there aren't really any issues.
Another way you could reference App from Task would be a Singleton pattern or something similar, but that would probably be harder to test.
jsFiddle Demo
Generally bind would be used in this scenario assuming that the Task "class" didn't also setup other facilities which were not shown here.
Bind allows for the context to be provided for a function. This could be done in app's constructor. At which point only a function task would be required to call "someMethod".
function task(){
return this["someMethod"]();
}
function App(){
task.bind(this)();
}
App.prototype.someMethod = function(){
alert("Task needed access to this");
};
var a = new App();
However, if task must be a "class", and have other responsibilities then the prototype function could be shared.
function Task(){}
function App(){}
App.prototype.someMethod = Task.prototype.someMethod = function(){
alert("Task needed access to this");
};
var a = new App();
a.task();//->"Task needed access to this"
var t = new Task();
t.someMethod();//->"Task needed access to this"
Your app instances and task instances are tightly bound. App instances have tasks and this can be fine.
A design of loosely coupled objects is more flexible and easier to extend but more complicated to initially create. One such pattern is using a mediator/publish subscriber and have app raise an event/publish message any other object function can listen to this and take action on the event.
For example: your app creates an Ajax instance and when that instance is done it raises some event (fetchedData for example). A listener could be DomDependent.updateView function but later you may want to add/remove/change the order of tasks to do after data is fetched. This can all be configured in a app.init function or per procedure in a controller that kicks of certain procedures (like log in, search, ...).
Instead of creating a whole bunch of specific functions in Ajax (fetchUserPrefs, login, search, ...) you can create one general function and have the controller add listeners or pass the next event when fetchData is complete to run the correct next function.
Here is some pseudo code:
var app = {
init:function(){
mediator.add("updateLogin",domDependent.updateView);
mediator.add("updateLogin",app.loadUserPrefs);
mediator.add("failLogin",domDependent.updateView);
},
login: function(){
mediator.trigger("loadingSometing",{type:"login"});
ajax.fetch({
onComplete:"updateLogin",//what listens to updateLogin you decided in init
onFail:"failLogin",
loginDetails:domDependent.getLogin(),
url:settings.loginUrl,
type:"post"
});
}
}
var ajax = {
fetch:function(data){
data = data || {};
//simple check for onComplete, it's mandatory
var complete = data.onComplete || app.raiseError("ajax.fetch needs onComplete");
//other code to validate data and making ajax request
onSuccess:function(resp){
//mutate data object as the mediator will pass it to
// whatever other function is called next
// you don't hard code domDependent.updateView and
// app.loadUserPrefs because fetch can be used generally and
// success may have to do completely different things after its done
// and you want to define procedures in init, not all over your code
data.response=resp;
//trigger event to do whatever needs to be done next
mediator.trigger(complete,data);
}
}
}
As you can see it gets complicated and maybe doesn't look like code you're used to but it's highly configurable.
I may have misunderstood the advantages of the mediator pattern to loose couple and if so please comment. I use it to:
Make methods more general instead of copying a lot of logic only
because what to do after it's done is different. In fetch the ajax
object just fetches, this would be the same for login or getting
user preferences, the only thing different is what function to call
next/on error when it's done.
A procedure like login involves multiple functions in multiple
objects if this function chain hard code what to do next once a
particular function is done your procedure of login is defined all
over your code. When defining it in init/config you can easily change the
order or add/remove functions in the chain.
I have a component which works fine using AJAX and mootools. Currently the view.raw.php only has one function in it which is display. I've been trying to create other functions within the component to use from AJAX but I can't make it work.
I thought that the ajax call is:
url: 'index.php?option=com_optical_database&view=gender&task=hello&format=raw',
with a public function within the component called hello:
public function hello(){
but it ignores this and goes to the display function every time. Is there a way of avoiding this?
Look at the place where the GET parameter task is used.
In Joomla there is usually a switch statement for this, and when you want to define a new task, you first need to add a new case in this switch.