Angular JS - On click load controller function - javascript

I'm creating a small event app with angular for practicing. Currently i've created a application with Laravel 5.1 and returning some URL's with JSON. I load those URL's in my Factory for the events. Those events will be rendered with Angular. After they are rendered, a button with "Show info" will be placed and when you click at it, i want to call a function in the EventController so my $scope.event will receive the new data. My Controller has a function with $scope.getEvent(eventID); but i cant figure out how to run that function on click.
//Controller
app.controller('EventController', ['$scope', 'eventFactory', '$http', function ( $scope, eventFactory, $http )
{
eventFactory.getEvents(1).then(function(response){
$scope.events = response.events;
$scope.eventPaginator = response.pagination;
});
$scope.getEvent = function(value){
console.log('trigger');
eventFactory.getEvent(value).then(function(response){
$scope.event = response;
});
};
$scope.loadPage = function(page){
eventFactory.getEvents(page).then(function(response){
$scope.events = response.events;
$scope.eventPaginator = response.pagination;
});
};
}]);
//Directive
app.directive('event', function() {
return {
restrict: 'E',
scope: {
data: '=',
loadEvent: '&',
},
templateUrl: '/assets/website/angular/views/event.html',
link: function(scope, element){
scope.loadEvent(function(){
alert('Click')
});
},
};
});
//Factory
app.factory('eventFactory', ['$http', function ( $http )
{
return {
getEvents: function (page)
{
return $http.get('/api/v1/events?page='+page)
.then(function ( response )
{
return response.data;
});
},
getEvent: function (id)
{
return $http.get('/api/v1/event/'+id)
.then(function ( response )
{
return response.data;
});
}
};
}]);
//View
<div class="event">
<h2>[[data.event.title]] ID: [[data.event.id]]</h2>
<div class="event-image">
</div>
<div ng-click="loadEvent(data.event.id)">Click voor [[data.event.id]]</div>
</div>
//HTML code for the Laravel View
<div class="col-md-9" ng-controller="EventController">
<div class="btn btn-success" ng-click="getEvent(15)">Test</div>
<div class="row">
<h1 ng-bind="showEvent.event.title"></h1>
{#<div class="col-md-12">#}
{#<h1 class="page-header">Page Heading <small>Secondary Text</small></h1>#}
{#<div ng-controller="BannerController">#}
{#<ul rn-carousel rn-carousel-auto-slide="3" rn-carousel-transition="slide" rn-carousel-duration="1000" class="image carousel">#}
{#<li ng-repeat="banner in banners">#}
{#<img ng-src="[[banner.image]]" alt="" class="img-responsive">#}
{#</li>#}
{#</ul>#}
{#</div>#}
{#</div>#}
<div class="col-sm-12">
<div class="row">
<div class="col-sm-4" ng-repeat="event in events">
<h1>Een event</h1>
<event data="event"></event>
</div>
</div>
</div>
<div class="col-sm-12">
<h3>[[eventPaginator.total]]</h3>
<div class="pagination">
<div ng-repeat="n in [] | range:eventPaginator.total">
<button ng-click="loadPage(n+1)">[[n+1]]</button>
</div>
</div>
</div>
</div>
</div>

I think you wanted to call the parent controller function from the directive template with passing id parameter to it. For that you need to pass the method reference to the directive in by adding load-event attribute with getEvent(id) on the directive element.
Also you should remove the unwanted link which has wrong code in it.
//below code should remove from the directive.
scope.loadEvent(function(){
alert('Click')
});
Directive Template
<event data="event" load-event="getEvent(id)"></event>
Template
<div ng-click="loadEvent({id: data.event.id})">Click voor [[data.event.id]]</div>

Related

How to reinitialize AngularJS 1 Controller for only 1 element

I have 2 HTML Element with the same Controller but different ng-init('value').
HTML
<div id="open-status" ng-controller="MainController" ng-init="init('open')">
<div ng-repeat="status in statusList">
{{ status.name }}
</div>
</div>
<div id="closed-status" ng-controller="MainController" ng-init="init('closed')">
<div ng-repeat="status in statusList">
{{ status.name }}
</div>
</div>
<button id="reload-open-status-only">Reload</button>
Javascript/Jquery/AngularJS
.controller("MainController", function($scope, dataService) {
$scope.init = function(myType) {
dataService.ajaxThis($config).then( function mySuccess(response) {
$scope.statusList = response.data;
}, function myError(response) {
// ERROR: NO RESPONSE FROM THE AJAX URL
alert('Ajax error! Status not fetched. Please try again later.');
});
$scope.$on('reloadMe', function(e, args){
$scope.init(args);
})
});
$(document).on('click', '#reload-open-status-only', function($rootScope, $timeout){
$timeout(function() {
$rootScope.$broadcast('reloadMe', 'open');
}, 1000);
});
Now, this is working fine. The problem is both of my element are reloading. What is the right way to reload a single ng-controller without using different angular controllers.
EDIT
added a parameter to my broadcast like this
$rootScope.$broadcast('reloadMe', 'open', 'open-status');
and to my controller
angular.element($('#' + id)).scope.init(args);
but i'm having an error:
angular.element(...).scope.init is not a function
angular.element($('#' + id)).scope().init(args);
worked .. just added () after scope.

AngularJs get data from $http before controller init

I have a simple angularjs application, in which I want to run a slider and the slider elements come from $http request.
Here is the code for reference:
var mainApp = angular.module("myapp", []);
mainApp.run(['$rootScope', '$http',
function($rootScope, $http) {
$http.post('process.php?ajax_type=getChild').success(function(data) {
if (data.success) {
console.log(data.child); // data received...
$rootScope.categories = data.child;
}
});
}]);
mainApp.controller('gridChildController', function($scope, $http, $rootScope) {
console.log($rootScope.categories); // this is also null....
$scope.brands = $rootScope.categories;
$scope.finished = function(){
jQuery('.brand_slider').iosSlider({
desktopClickDrag: true,
snapToChildren: true,
infiniteSlider: false,
navNextSelector: '.brands-next',
navPrevSelector: '.brands-prev',
lastSlideOffset: 3,
onSlideChange: function (args) {
}
});
};
});
Here is code of the template file:
<div ng-app="myapp">
<div ng-controller="gridChildController" class="brand_slider" >
<div class='slider'>
<div class="slide col-md-5ths col-sm-4 col-xs-12 text-center" ng-repeat="x in brands" ng-init="$last && finished()">
<img class="img-responsive center-block" ng-src="{{x.image}}" title="{{x.title}}" alt="{{x.title}}">
</div>
</div>
</div>
</div>
When I run this code, I get the data from the $http but ng-repeat doesn't work, and in the controller I get data null.
If you put something on $rootScope it will be also available on the child scopes. So you can bind straight to categories (no need to copy it to $scope.brands):
ng-repeat="x in categories"

Updating Angular scope variables from $http.get call

I'm fairly new to Angular, and I'm trying to figure out why scope variables isn't updating after they've been set.
I'm calling a Node API returing json objects containing my data. Everything seems to work fine except setting $scope.profile to the data returned from the API.
Setup:
app.js
(function() {
var app = angular.module("gamedin", []);
app.controller('profileController', function($scope, $http, $timeout) {
$scope.profile = {};
$scope.getProfile = function() {
var vanityUrl = $scope.text.substr($scope.text.lastIndexOf('/') + 1);
$http.get('/steamid/' + vanityUrl)
.then(function(data) {
$http.get('/profile/' + data.data.response.steamid)
.then(function(data) {
console.log(data.data.response.players[0]); // Correct data
$scope.profile = data.data.response.players[0]; // View isn't updated
})
})
// Reset the input text
$scope.text = "";
}
});
...
app.directive('giHeader', function() {
return {
restrict: 'E',
templateUrl: 'components/header/template.html'
};
})
app.directive('giProfile', function() {
return {
restrict: 'E',
templateUrl: 'components/profile/template.html'
}
})
})();
components/header/template.html
<header>
<div class="header-content" ng-controller="profileController">
<div class="col-md-3"></div>
<div class="col-md-6">
<div class="header-content-inner">
<input ng-model="text" ng-keyup="$event.keyCode == 13 && getProfile()" class="form-control" type="text" placeholder="Enter Steam URL">
</div>
<p>e.g., http://steamcommunity.com/id/verydankprofilelink</p>
</div>
<div class="col-md-3"></div>
</div>
</header>
components/profile/template.html
<div class="container">
<div ng-controller="profileController">
<h3>
<strong>Username: {{ profile.personaname }}</strong>
</h3>
<p> SteamID: {{ profile.steamid }}</p>
</div>
</div>
index.html
<!doctype html>
<html ng-app="gamedin">
<head>
...
</head>
<body>
...
<gi-header></gi-header>
<gi-profile></gi-profile>
...
</body>
</html>
I've tried wrapping it in $scope.$apply, like this
$scope.$apply(function () {
$scope.profile = data.data.response.players[0];
});
... which resulted in Error: [$rootScope:inprog]
Then I tried
$timeout(function () {
$scope.profile = data.data.response.players[0];
}, 0);
and
$scope.$evalAsync(function() {
$scope.profile = data.data.response.players[0];
});
... and although no errors were thrown, the view still wasn't updated.
I realize that I'm probably not understanding some aspects of angular correctly, so please enlighten me!
The problem is that you have 2 instances of profileController, one in each directive template. They should both share the same instance, because what happens now is that one instance updates profile variable on its scope, and the other is not aware. I.e., the profileController instance of header template is executing the call, and you expect to see the change on the profile template.
You need a restructure. I suggest use the controller in the page that uses the directive, and share the profile object in both directives:
<gi-header profile="profile"></gi-header>
<gi-profile profile="profile"></gi-profile>
And in each directive:
return {
restrict: 'E',
scope: {
profile: '='
},
templateUrl: 'components/header/template.html'
};
And on a more general note - if you want to use a controller in a directive, you should probably use the directive's "controller" property.
Try using this method instead:
$http.get('/steamid/' + vanityUrl)
.then(function(data) {
return $http.get('/profile/' + data.data.response.steamid).then(function(data) {
return data;
});
})
.then(function(data) {
$scope.profile = data.data.response.players[0]; // View isn't updated
})
Where you use two resolves instead of one and then update the scope from the second resolve.

Angularjs : Print object from control to view with ionic

I try to build new APP with ionic framework and Angularjs.
Now my problem is i cannot show the result from controller to view. I try open console.log(allposts); in my browser ans we show the result good.
But in view its not show any thing
allpost.html
<dive class="item itemfull" ng-repeat="post in allpost">
<div class="item item-body">
<div>{{ post.title }}
<div class="title-news"><div class="title" ng-bind-html="post.content"></div></div>
</div>
</div>
</div>
And the controller
myApp.controller('allpost', function($scope , $http , $stateParams , Allposts) {
var id = $stateParams.id;
$scope.post = Allposts.GetAllposts(id);
});
myApp.factory('Allposts',['$http', '$q',function($http,$q){
var allposts = [];
var pages = null;
return {
GetAllposts: function (id) {
return $http.get("http://kotshgfx.info/azkarserv/?json=get_category_posts&id="+id+"&status=publish",{params: null}).then(function (response) {
items = response.data.posts;
allposts = items;
console.log(allposts);
return items;
$ionicLoading.hide();
});
}
}
}]);
Where is error ?
try to change the code like this in controller and factory in js files
.controller('allpost', function ($scope, $http, $stateParams, Allposts) {
var id = $stateParams.id;
Allposts.GetAllposts(id).then(
function (response) {
$scope.allPosts = response.data.posts;
});
})
.factory('Allposts', ['$http', '$q', function ($http, $q) {
return {
GetAllposts: function (id) {
return $http.get("http://kotshgfx.info/azkarserv/?json=get_category_posts&id=" +
id + "&status=publish");
}
}
}]);
the html file
<div class="item itemfull" ng-repeat="post in allPosts">
<div class="item item-body">
<div>{{ post.title }}
<div class="title-news">
<div class="title" ng-bind-html="post.content"></div>
</div>
</div>
</div>
</div>
It works for my test

AngularJS with UI-Route and Master Detail

I'm trying to get JSON data from my server and display them into my website. I am using Ui-router extension. What I am looking for here is a master-detail setup.
Index.html
<input ng-model="manga.name" ng-change="searchManga()" id="search" type="search" placeholder="Manga İsmi Girin..." required>
<div class="row" ui-view="viewA">
<div class="col s8 offset-s1" ng-controller = "nbgCtrl">
<div class="row">
<div class="col s12 m6 l4" ng-repeat = "manga in mangas">
<div class="row">
<div class="col s5">
<a ui-sref="ui-sref="#/manga/{{manga.id}}"" class="thumbnail">
<img src="/kapaklar/{{manga.kapak}}">
</a>
</div>
<div class="col s7">
<p>{{manga.ad}}</p>
<a href="" class="waves-effect waves-light btn">
</a>
I have above a main page and repeating some thumbnails. Every thumbnail links to its detailed information page. And when clicking a thumbnail it has to carry its own data and load it here. Here's what I've got so far:
JS:
angular.module('nasuh',["ui.router"])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('list', {
url: "/",
controller: "ListCtrl",
templateUrl: "index.html",
}
)
$stateProvider
.state('icerik', {
url: "/icerik/:{{mangaid}}",
controller: "mmgCtrl",
views: {
"viewA": { templateUrl: "icerik.html" },
}
}
)
})
.factory('Mangas', function($http){
var factory = {};
function getData(manganame, callbak) {
var url = '/uzak/remote.php?callback=JSON_CALLBACK';
$http.get(url).success(function(data){
factory = data.results;
callback(data.results);
})
}
return {
list: getData,
find: function(name, callback) {
console.log(name);
var manga = cachedData.filter(function(entry) {
return entry.id == name;
})[0];
callback(manga);
}
};
})
.controller('ListCtrl', function($scope, $http, Mangas) {
$scope.manga = {
name: '' }
$scope.searchManga = function() {
Mangas.list($scope.manga.name, function(mangas) {
$scope.mangas = mangas;
});
}
})
.controller('mmgCtrl', function($scope, $http, $stateParams, Mangas) {
Mangas.find($stateParams.mangaid, function(manga) {
$scope.manga = manga;
});
})
I just doubt that the getData is not a promise in resolve closure you hava returned MY.isimler.then so in mmgCtrl controller first console getData to make sure it's a promise or data

Categories

Resources