I have a bunch of radio groups and a textarea elements that load in a ng-repeat controller. I want to populate all/some of those controls after the controller has finished loading them. I have tried $scope.$on. I have looked at directives, but they are really confusing.
I just want to call a function to populate the form (manipulate DOM) after the controller has finished loading. The controller currently loads (and loads a sub-controller) on the click of a button.
Here's some example code of what I have. The Risks function is what I am calling when the button is clicked.
myApp.controller('spRisks', function ($scope, $http, Service) {
$scope.getRisks = function(){
var caml = "<View><Query><Where><Eq><FieldRef Name='Owner'/><Value Type='Integer'><UserID/></Value></Eq></Where></Query></View>";
var ownerData = getDataWithCaml("Owners", caml);
ownerData.success(function (data) {
var arrayOfExpressions = [];
for (var i = 0; i < data.d.results.length; i++){
arrayOfExpressions.push(CamlBuilder.Expression().LookupMultiField("OwnerTitle").EqualTo(data.d.results[i].Title));
}
var newCaml = new CamlBuilder().View().Query().Where()
.Any(arrayOfExpressions)
.And()
.TextField("Control").IsNotNull()
.ToString();
newCaml = newCaml.replace(/"/g, '\'');
var jsonData = getDataWithCaml("Risks", newCaml);
jsonData.success(function (jsonDataResults) {
$scope.$apply(function(){$scope.Risks = jsonDataResults.d.results;});
});
jQuery('#divQs').show();
});
$scope.$on('$viewContentLoaded', function () {
alert('test');
Service.getAnswers($('#selYear').val(), $('#selMonth').val());
});
}
});
Related
I am trying to make a comments section on my website. I have properly linked all my files and getting data from Firebase is working. But, the comments only load after I either click on something or enter text in the "Add comment" field; it does not show the comments instantly when the page loads. Does anyone know why?
Relevant code: (placed at the top of my controller)
$scope.comments = {};
database.ref('comments').on('value', function(items) {
$scope.comments = items.val();
});
$scope.comment = function() {
database.ref('comments').push($scope.newComment);
$scope.newComment = "";
};
Use $scope.$apply
$scope.comments = {};
database.ref('comments').on('value', function(items) {
$scope.$apply(function () {
$scope.comments = items.val();
});
});
$scope.comment = function() {
database.ref('comments').push($scope.newComment);
$scope.newComment = "";
};
So I am trying to make load more function.I am fetching data from twitch API and it comes as array of objects.
$scope.loadData = function () {
$http.get("https://api.twitch.tv/kraken/streams?limit=9&offset=" + $scope.x).then(function(response) {
$scope.myName = response.data.streams;
$scope.link="http://player.twitch.tv/?channel=";
return $scope.x=$scope.x + 9; }); };
//initial load
$scope.loadData();
$scope.myName is array in which data is stored and it is used in ng-repeat.
$scope.x is variable used for offset and after clicking button it is incremented and is used to fetch new streams.So when I click button it removes old 9 streams and loads new 9 streams.I want to keep my old 9 streams and to just add 9 more everytime button is clicked.
See here: https://plnkr.co/edit/TbOf9hkPILJn2snW8D7A Thanks.
If I understood problem well, you should just append your data array instead of replacing it:
$scope.myName = [];
$scope.loadData = function () {
$http.get("https://api.twitch.tv/kraken/streams?limit=9&offset=" + $scope.x).then(function(response) {
// add streams to existing array
Array.prototype.push.apply($scope.myName, response.data.streams);
$scope.link="http://player.twitch.tv/?channel=";
return $scope.x=$scope.x + 9; }); };
//initial load
$scope.loadData();
HERE IS THE SOLUTION OF PLNKR
I've modified Streamovi controller and added load more button at the bottom so you can trigger loading more
app.controller('Streamovi', function($scope, $http) {
var ITEMS_PER_LOAD = 9;
var offset = 0;
$scope.myName = [];
function loadStreams(){
$http.get("https://api.twitch.tv/kraken/streams?limit="+ITEMS_PER_LOAD+'&offset='+offset).then(function(response) {
$scope.myName = $scope.myName.concat(response.data.streams);
$scope.link="http://player.twitch.tv/?channel=";
offset+=ITEMS_PER_LOAD;
});
}
//handler for the "Load More" button in the view.
$scope.loadMore = function(){
loadStreams();
}
//initial Loading
loadStreams();
});
Here is my code brief:
controller:
angular.module('testApp').controller('TestCtrl', function ($scope, EssayRsc, EssaySvc) {
$scope.pageInfo = EssaySvc;
}
service:
angular.module('testApp').service('EssaySvc', function (EssayRsc, $document, $rootScope) {
var count = 1;
var essayList = [{title:11111},{title:11111},{title:11111},{title:11111},{title:11111},{title:11111},{title:11111}];
var pageNum = null;
var pages = null;
$document.scroll(function () {
if ($document.height() == ($document.scrollTop() + angular.element(window).height())) {
EssayRsc.get({pageSize:count}, function (resp) {
essayList = essayList.concat(resp.list);
pageNum = resp.pageNum;
pages = resp.pages;
this.essayList = essayList;
// this changes here but not changes in the controller
console.log(this.essayList);
});
}
});
this.essayList = essayList;
this.pageNum = pageNum;
this.pages = pages;
})
html:
<ul class="no-bullet" ng-repeat="essay in pageInfo.essayList">
<li class="essay-query-li" ng-click="viewEssay(essay.id)">{{essay.title}}</li>
</ul>
This is my question:
I want to set a listener in a service,so erverytime I scroll to the bottom of the window it can load one record.
but everytime essayList attribute in the service changed,but in the controller and view it never change, i really cannot figure out why and how to solve it,if you know the answer please tell me, thanks a lot!
i'm building an app with angularjs, i have implemented infinite scrolling technique because i have a lot of items to show, so it's a better experience than pagination, but the bad thing that i'm having it's that if the user clicks on item it goes to item page, but when he wants to go back he will be on the top and he should keep scrolling. that's what i want to accomplish if he hits back button he could back to his position where he were !!
Listing Items:
<div class="container" id="infinit-container" ng-controller="ArticlesController">
<div id="fixed" when-scrolled="LoadMore()">
<div ng-repeat="article in Articles">
<article-post article="article"></article-post>
</div>
</div>
</div>
here is when-scrolled directive
app.directive('whenScrolled', function () {
return function (scope, element, attrs) {
$('#fixed').height($(window).height());
var div = element[0];
element.bind('scroll', function () {
if (div.scrollTop + div.offsetHeight >= div.scrollHeight) {
scope.$apply(attrs.whenScrolled);
}
})
}
})
thats the controller
app.controller('ArticlesController', function ($scope, UserService) {
$scope.Articles = [];
var page = 0;
$scope.LoadMore = function () {
UserService.Articles(page)
.success(function (data) {
$scope.Articles.push.apply($scope.Articles, data);
});
page++;
};
$scope.LoadMore();
});
im using page number, save page number somewhere (i prefer sessionStorage) when going to see the item detail , when user is comming back to list, read page number and load the page.
it is the simple code for main page controller (list)
app.controller('ArticlesController', function($scope, UserService) {
$scope.Articles = [];
var page = 0;
$scope.LoadMore = function() {
UserService.Articles(page)
.success(function(data) {
$scope.Articles.push.apply($scope.Articles, data);
});
page++;
}
$scope.LoadArticle = function(articleId) {
sessionStorage.setItem("pageNumber", page);
/// change path to somewhere you want show your article
};
//it will load the page you coming back from
if (sessionStorage["pageNumber"]) {
page = parseInt(sessionStorage["pageNumber"]);
}
LoadMore();
});
because of using sessionStorage , it will deleted if user close the browser or page as expected.
I'm trying to build out a dynamic list of UI elements. I can hard code the UI list now, and everything works fine. I want this to be extensible however, so I'm trying to figure a way of passing id tags and corresponding functions to be called. Essentially, the callback function for my ajax call isn't being executed, though I am posting the correct data, and receiving the correct response. Here's the code:
myModule = function () {
var titleUI = Object.create(ChainUI());
var memcachedId = '<?php echo $memcachedId;?>';
return {
printChain: function(data) {
alert("printchain");
var territories = jQuery.parseJSON(data);
titleUI.makeChainTable();
territories.forEach(function(territory) {
titleUI.territoryDisplay(territory);
});
titleUI.tableDecorator($('#chainTable'));
},
loadChain: function() {
titleUI.destroyChainTable();
var url = 'traffichandler.php';
var instruction = {'instruction': 'titleChain', 'method': 'printChain', 'memcachedId': memcachedId.toString()};
$.post(url, instruction, this.printChain);
},
loadDefault: function() {
titleUI.loadUI(['Title Chain'], [this.loadChain]);
}
};
}();
The corresponding titleUI code follows:
var ChainUI = function() {
return {
loadUI: function(uiList, funcList) {
$('#uiFunctions').empty();
for(var i in uiList) {
var toDom = '<li id="'+uiList[i]+'">';
toDom += uiList[i];
toDom += '</li>';
$('#uiFunctions').html(toDom);
}
for(var i = 0; i < uiList.length; i++) {
var myFunc = funcList[i];
$('#uiFunctions').delegate($('#'+uiList[i]), "click",
function() {myFunc();}
);
}
},
}
In myModule.loadDefault, I can get this.loadChain to fire. I can't get this.printChain inside the $.post to work though. If remove all the dynamic stuff this.printChain works no problem. Don't get too hung up on the syntax, as is, the syntax is fine on my end. How can I get the ajax call back to work? Thanks!