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
Related
I am beginning to use Angularjs. I have this working properly.
There is a dynamically created sidebar listing all the styles.
There is a dynamically created navbar for sizes associated with that style.
When clicked style is "selected" properly.
When clicked size is "selected" properly.
I want these two selections to be parameters in a url that I GET and display within a specific DIV. So the url would look like ...http://xxxddd.com/inventory/{{style}}/{{size}}
I have absolutely no idea where to go from here.
<script>
var app = angular.module("alt", []);
app.controller('StyleController', function(){
this.style = '';
this.selectStyle = function(newValue){
this.style = newValue;
};
this.isSelected = function(styleName){
return this.style === styleName;
};
});
app.controller('SizeController', function(){
this.size = '';
this.selectSize = function(newValue){
this.size = newValue;
};
this.isSelected = function(sizeName){
return this.size === sizeName;
};
});
</script>
I am very new at angular. I hope someone can help me. This is the main hangup with my project right now.
Thanks in advance.
You will want to create a service that utilizes AngularJS' $http library to make a GET request. Look at the documentation and see how to pass parameters (style/size).
You will then want to use AngularJS' Dependency Injection (DI) to inject your service into your controller and call its method which has the $http call.
I am very much new in AngularJS and due to which I am facing an issue and not able to understand the exact problem. The code which I tried is worked in normal javascript code but now I want to use custom service (factory function). Actually, I have a textarea where user can input their text and then they can do the formating by selecting any of the text. (discovertheweb.in/woweditor - this is existing site which I have created now I want to apply angular in this code). Now, I have created a custom service to check whether the user select any content or not. I have used the below code in my custom services and try to get the selection start, end point so that I can get the selected text from the textarea field. But, the problem is that I am getting 0 value for both selection start and end point. When i used the same code inside directive it works but try to get the value through service it is showing 0 for both. Please find the below code and let me know the code which I missed out here.
Custom Service:
(function(){
"use strict";
var wsApp = angular.module("WorkApp");
wsApp.factory("InputCheckService", function(){
var defaultText = document.getElementById("input-text-area");
var selStart = defaultText.selectionStart;
var selEnd = defaultText.selectionEnd;
var selectedText;
if(selStart != selEnd){
selectedText = defaultText.value.substring(selStart, selEnd);
}else{
selectedText = null;
}
return {
selStart: selStart,
defaultText: defaultText,
selEnd: selEnd,
selectedText: selectedText
};
});
}());
The directive where I called this services. I already included the service inside the main controller in different file.
(function(){
"use strict";
var wsApp = angular.module("WorkApp");
wsApp.directive("generalDirective", generalDirective);
function generalDirective(){
return {
scope: true,
controller:function($scope, InputCheckService){
$scope.collapsed = false;
$scope.CollpasePanel = function(){
$scope.collapsed = !$scope.collapsed;
};
$scope.updatePara = function(){
alert(InputCheckService.defaultText+"Selection start: "+InputCheckService.selStart+" Selection End: "+ InputCheckService);
/**
* defaultText: defaultText,
selStart: selStart,
selEnd: selEnd,
selectedText: selectedText
*/
}
},
templateUrl: 'directive/general-directive.html'
};
}
}());
If you need any more details, please let me know.
Thanks in advance for your time and suggestion.
Regards,
Robin
You should not use service to manipulate DOM element. You should manipulate DOM only at directives. Your problem is you DONT have anywhere to listen to TEXTAREA SELECTION EVENT and your service will not update the data inside. I have created a fiddle for your problem. The watchSelection directive is based on this answer from stackoverflow. Something you should notice :
I use service only to store data. Something like selStart, selEnd or paragraphContent and provide some API to retrieve the data
.factory("InputCheckService", function () {
return {
setSelStart: function (start) {
selStart = start;
},
.....
},
});
On the watchSelection directive, you watch for the mouseup event and will perform update the service so that it will store value you need and later you can retrieve it from other directives or controllers.
elem.on('mouseup', function () {
var start = elem[0].selectionStart;
//store it to the service
InputCheckService.setSelStart(start);
});
In your generalDirective directive you can get value from your service and angular will auto update the view for you.
Hope it helps.
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
I am writing my first non-trival Angular App and I have hit a snag with a directive. The directive takes data from a controller's scope and applies it to Google Chart. The chart is not the issue - which is to say it works fine with dummy data - it is access to the properties of the scope object which were obtained via http:
I am accessing data returned via an API in a service which utilizes $http:
dashboardServices.factory('SearchList', ['$http','$q',
function($http, $q){
return {
getSearchDetails:function(searchType, resultType){
return $http.get("api/searches/"+searchType+"/"+resultType)
.then(function(response){
if (typeof(response.data === 'object')) {
return response.data;
} else {
return $q.reject(response.data);
}
},function(response){
$q.reject(response.data);
});
}
}
}]);
In my controller, I am taking the response from this service and attaching to my scope via the promises' "then" method:
dashboardControllers.controller('DashboardCtrl', ['$scope', 'SearchList',
function($scope, SearchList){
$scope.searchData = {};
$scope.searchData.chartTitle="Search Result Performance"
SearchList.getSearchDetails("all", "count").then(function(response){
$scope.searchData.total = response.value; //value is the key from my API
});
SearchList.getSearchDetails("no_results", "count").then(function(response){
$scope.searchData.noResults = response.value;
});
}]);
To an extent this works fine, i can then use the 2-way binding to print out the values in the view AS TEXT. Note: I want to be able to write the values as text as I am trying to use a single scope object for both the chart and the textual data.
{{searchData.total | number}}
As mentioned, I have written a directive that will print a specific chart for this data, in this directive ONLY the $scope.searchData.chartTitle property is accessible. The values that were set in the then functions are not accessible in the directive's link method:
Here is the directive:
statsApp.directive('searchResultsPieChart', function(){
return{
restrict : "A",
scope:{
vals:'#vals'
},
link: function($scope, $elem, $attr){
var dt_data = $scope.vals;
var dt = new google.visualization.DataTable();
dt.addColumn("string","Result Type")
dt.addColumn("number","Total")
dt.addRow(["Successful Searches",dt_data.total]);
dt.addRow(["No Results",dt_data.noResults]);
var options = {};
options.title = $scope.vals.title;
var googleChart = new google.visualization.PieChart($elem[0]);
googleChart.draw(dt,options)
}
}
});
Here is how I am using the directive in the view:
<div search-results-pie-chart vals="{{searchData}}"></div>
I can see that the issue is that the numeric values are not available to the directive despite being available when bound to the view.
Clearly the directive needs to be called later when these items are available or via some callback (or perhaps an entirely different approach), unfortunately i am not sure why this is the case or how to go about solving.
Any help would be greatly appreciated. I hope this makes sense.
I think the following will help you.
First change the directive scope binding for vals to use = instead of # (see this question for good explanation of the differences - basically # interpolates the value whereas = binds to the variable in the parent scope)
Then, move the part of the directive that creates the graph into a render function within your link function.
Then, $watch vals for any changes, then call the render function with the new values
You would also have to slightly change the approach of using ele[0], as you'll need to clear out the contents of it and add a new element with the new chart when the data changes (otherwise many charts will be added as the data changes!)
Here is an example of what to do in your link function with regard to the $watch and new render function (changing the $scope binding like I mentioned is not shown):
$scope.$watch('vals', function(newVals, oldVals) {
return $scope.render(newVals);
}, true);
$scope.render = function (dt_data) {
var dt = new google.visualization.DataTable();
dt.addColumn("string","Result Type")
dt.addColumn("number","Total")
dt.addRow(["Successful Searches",dt_data.total]);
dt.addRow(["No Results",dt_data.noResults]);
var options = {};
options.title = $scope.vals.title;
var googleChart = new google.visualization.PieChart($elem[0]);
googleChart.draw(dt,options)
}
Hope this helps you out!!!
I have a service for storing some application common data. This service can also modify this data and react to events. However I am having trouble with propagating the changes to controllers that are using this service.
I've seen this question and this question, but the solutions don't work for me.
I created a plunker that shows what is my core problem. There is a service object storing common data in sharedObject. It has a function updateObject, which can update the data (in my real app it sends a request to a server). The service is used by main controller. However, when updateObject is called in the service, data are not updated in the controller.
Why is that? Also is this a best practice or am I doing somethign wrong?
Here's the code:
app = angular.module('app', []);
app.factory('object', ['$timeout', function($timeout){
var sharedObject = {attr1: '', attr2: ''};
var updateObject = function() {
$timeout(function(){
sharedObject = {attr1: 'new value', attr2: 'update value'};
console.log('updated');
}, 1000);
}
updateObject();
return sharedObject;
}]);
app.controller('main', [
'$scope', 'object', function($scope, object) {
$scope.$watch(function(){return object}, function(obj){
console.log(obj);
$scope.object1 = obj;
}, true);
}
]);
The problem is that the timeout callback doesn't update the object you're watching. It replaces it by another object. So the watcher still sees the old object, unmodified.
Replace the code, as in this updated plunker, by
sharedObject.attr1 ='new value';
sharedObject.attr2 = 'update value';
and you'll see the values change in the page.
The problem is that you are replacing the object that sharedObject points initially with another object altogether in update method.
You controller would be still holding the reference to the older object.
What you need to do is update the sharedObject in place. See my updated plunkr
Basically you need to do something like this in update method
sharedObject.attr1= 'new value';
sharedObject.attr2= 'update value';