Trigger angular from outside of angular-app - angularjs

Ho to trigger an event inside ngApp from the outside world?
This is my current code:
// Inside old code
console.log("Start Triggering angular");
$('#issueSelectedPid').val(pid);
$('#issueSelectedPid').trigger('input');
console.log("Triggering angular");
// inside ngApp
<input id="issueSelectedPid" ng-model="vm.selectedPid" ng-change="vm.doMyStuffTriggerdFromTheOutsideWorld()" />
Are there better ways of doing this?
Thanks for any help
Larsi

You can access the scope using the below code :
var appElement = document.querySelector('[ng-app=appName]');
var appScope = angular.element(appElement).scope();
var controllerScope = appScope.$$childHead;
controllerScope.functionName(controllerScope.vm.doMyStuffTriggerdFromTheOutsideWorld() in your case)

you need to get your html element by yourDivId which is defining your input scope, then call $apply with something or without
var scope = angular.element($("#yourDivId")).scope();
scope.$apply(function(){
scope.something= 'something';
})

Related

Compile inside a controller

The problem occurs as follows,
$scope.name = "Maximilian";
var template = "<div><span>{{name}}</span></div>";
var content = $compile(template)($scope);
console.info(content); //shows compiled innerText
$scope.outputContainer = content[0].innerText; // shows uncompiled Content
what am i doing wrong?
One possible solution is to put it into a 0 second $timeout-function.
If there is a better one let me know.
$timeout(function(){
$scope.outputContainer = content[0].innerHTML;
});
http://jsfiddle.net/cLenjedL/1/
I think you are looking for an evaluated content.
your controller could look like this.
function TodoCtrl($scope) {
$scope.name = "Maximilian";
var template = "<div><span>"+$scope.$eval("name")+"</span></div>";
$scope.outputContainer = template;
}
Personally I would create a directive and use the transclude function for the html snippet.
I have updated your js fiddle

Angular Update Doom from Controller without using $Scope

i really need some help here with angular... this time i have no idea at all.
I want to update my doom, Angular Element using my controller.
For example:
HTML code:
<div ng-controller="UpdateController as UC">
{{UC.updateText}}
<button ng-click="UC.updateIt()"/>
</div>
js code:
angular.controller('UpdateController', function(){
this.updateText = 'Text to Update';
this.updateIt = function(){
// Here i need to update this.updateText.
}
});
I have tried:
angular.controller('UpdateController', function(){
var updateText = this;
updateText.newText = 'Text to Update'
this.updateIt = function(){
updateText.newText = "my new text";
}
});
and i change the HTML as well to {{UC.updateText.newText}}
But it doesn't work, i can see all my changes in console.log();
I have tried multiple ways. using Watch (error, digest already running). and other variables and calls.
Can someone explain me how to do it using 'this.' ?
I don't wan't to use $scope, if i use $scope TAG it updates with no problem, but i don't wan't to give up using the 'this.' tag.
Also, i don't want to use element.angular, or jQuery.
Thanks!
You should be able to just use this.updateText = 'my new text'. It is however recommended to use a variable that is assigned to this as this may change when within a function inside the controller.
angular.controller('UpdateController', function(){
var vm = this;
vm.updateText = 'Text to Update';
vm.updateIt = function(){
vm.updateText = 'my new text';
}
});
Plunkr

Modifying factory value in directive Angular

I have the following code : http://codepen.io/Andarius/pen/Ggryge .
When the user draws a 'crop_area', the crop button should not be disabled anymore.
Why is the value no_crop_area (from the Image factory) not updated when drawing ?
Is it a scope problem ?
Also, I'm pretty new to AngularJS and was wondering what is the best practice when passing a factory to a controller (if there is one)
Given a factory :
myApp.factory('myFactory', function () {
return {foo:{bar:2}};
});
Is it better to do :
myApp.controller('myCtrl', ['myFactory',function (myFactory) {
var self = this;
self.foo = myFactory;
self.bar = myFactory.bar;
}]);
or
myApp.controller('myCtrl', ['myFactory',function (myFactory) {
var self = this;
self.foo = myFactory;
self.bar = self.foo.bar;
}]);
I have forked your code. Here is a working one.
http://codepen.io/anon/pen/qERpew?editors=101
The button is not getting enabled because, you are doing all the processing related to creating crop area by using javascript event handlers, so the code related to $scope (ie.angular related), will not come into effect. To have them in effect, you have to wrap the code related to $scope into $scope.$apply(function(){ // Your $scope variable update code.}).
PS: As per convention you should not use $scope name inside directive.Instead of that use scope.

Pass multiple values in $scope object in Angular.js

I am new in Angular.js and want to know more about it.
I just created a small project And want to pass multiple value with $scope object.
But it's not working properly.
Here what I am doing
function ListCtrl($scope, $http,Project) {
$http.get('/project').success(function(data){
str =data.result;
var result= str.replace('http://','domainname');
$scope.projects=data.rows;
$scope.projects=data.result;
});
}
In data variable I am getting rows and result.
And I am passing something like above with $scope.
Any help will be appreciated.
Try this,
$scope.projects = {};
$scope.projects.rows = data.rows;
$scope.projects.result = data.result;
Your problem is, that the view is not informed about the changes of the $scope.data variable, due to the fact that the value is changed in the async callback of the Promise which is returned by the $http.get() method.
Just wrap your $scope changes in a $scope.$apply method to run the digest loop:
$http.get('/project').success(function(data){
$scope.$apply(function() {
// Do scope changes here
})
}
Additionally you are assigning the value $scope.projects twice, so change this:
$scope.projects = {};
$scope.projects.rows = data.rows;
$scope.projects.results = data.result;
or just:
$scope.projects = data;
These two will overwrite each other.
$scope.projects=data.rows;
$scope.projects=data.result;
What you want to do might be more like this.
$scope.projects = {};
$scope.projects.rows = data.rows;
$scope.projects.result = data.result;
Then in your html if you want to display these, you can use ng-repeat to iterate over them and display each element. Do you have HTML to go with this that you are using?

Angularjs: ng-click has no method '$apply'

I append DOM element to body. Wrote the code in factory.
var templateElement = angular.element('<div class="popup modal-body"><div class="button-cancel" type="button" ng-click="closePopup()"></div>'+content+'</div>');
var scope = {};
scope.closePopup = function(){
var popup = angular.element(document.querySelector('.popup'));
popup.remove();
}
var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {
body.append(clonedElement);
});
everything works except the ng-click. I got this error when I click the div:
Uncaught TypeError: Object #<Object> has no method '$apply'
What did I do wrong? Thanks
According to the docs, the function returned by $compile() takes a Scope object as its first argument. You supply a normal JS object (which does not have an $apply method of course).
If you want to create a new scope, you can inject the $rootScope (through Dependency Injection) and use its $new() method:
app.factory('myFactory', function($rootScope) {
var scope = $rootScope.$new();
...
});
It seems a little bizarre to create an new scope inside a factory though, so providing more details on what you are ultimately trying to achieve might help someone suggest a better approach.

Resources