AngularJS display json by directive - javascript

I have little problem with AngularJS, I wanted to make directive to display json imported from other website, directive working, but it doesnt show anything from angular binds(when i was using this code by just putting it hardway, everything was working).
HTML
<div ng-app="docsIsolateScopeDirective">
<div ng-controller="Controller">
<my-post info="post"></my-post>
</div>
</div>
ANGULAR
(function(angular) {
'use strict';
angular.module('docsIsolateScopeDirective', ['ngSanitize', 'ui.bootstrap'])
.controller('Controller', ['$scope','$http','$sce', function($scope, $http, $sce) {
$http.get(link+'json=get_recent_posts&callback=&count=1').then(function(response, date, contents){
$scope.contents = response.data.posts;
$sce.trustAsHtml(contents);
});
}])
.directive('myPost', function() {
return {
restrict: 'E',
scope: {
customerInfo: '=info'
},
templateUrl: 'single-post.html'
};
});
})(window.angular);
SINGLE-POST.HTML
<article>
<div class="news-container">
<span class="news-category">{{content.categories[0].title}}</span>
<h1 class="news-title">{{content.title}}</h1>
<span class="news-date">{{content.date}}</span>
<div class="news-image">
<img src="{{content.thumbnail_images.full.url}}" />
</div>
<!-- .news-image -->
<div class="news-entry">
<p ng-bind-html="content.content">{{content.content}}</p>
</div>
</div>
Any ideas? :)

You save your response as
$scope.contents = response.data.posts;
And you pass into directive variable post . Maybe you should pass contents ?
And also in your directive you have customerInfo not content.

its always better to use jsonp for calls to outer domains.
Can you try doing this?
$http.jsonp('some/trusted/url', {jsonpCallbackParam: 'callback'})
Whitelisting urls is also apt.

Pass $scope.contents to info.
$scope.contents = response.data.posts;
<div ng-app="docsIsolateScopeDirective">
<div ng-controller="Controller">
<my-post info="contents"></my-post>
</div>
</div>

You need to use customerInfo in the template single-post.html and also pass contents scope object to your directive
Additionally, Using trustAsHtml() method correctly.
$scope.contents = $sce.trustAsHtml(response.data.posts);
Here is a simplified example:
(function(angular) {
'use strict';
angular.module('docsIsolateScopeDirective', [])
.controller('Controller', ['$scope',
function($scope) {
$scope.contents = {
title: "test"
};
}
])
.directive('myPost', function() {
return {
restrict: 'E',
scope: {
customerInfo: '=info'
},
template: '<article>\
<h1 class="news-title">{{customerInfo.title}}</h1>\
</article>'
};
});
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="docsIsolateScopeDirective">
<div ng-controller="Controller">
<my-post info="contents"></my-post>
</div>
</div>

Related

Angular directives, only one works per page

I have little problem with my angularJS directive, i want to display 2 photos in different way by using other html codes, but here comes a problem, that only one directive can works per page, the second one works only when i comment the previous one, there are no any errors in the browser console so i totally losing my mind trying to figure how to fix this problem.
ps displayed photos are taken form json file.
Angular:
(function(angular) {
'use strict';
angular.module('SinglePost', ['ngSanitize', 'ui.bootstrap'])
.controller('Controller', ['$scope', '$http', '$sce', '$location', function($scope, $http, $sce, $location) {
var weburl = document.URL;
var postId = weburl.substr(-2, 2)
$http.get(link + 'json=get_post&post_id=' + postId).then(function(response, date, content) {
$scope.content = response.data.post;
$scope.CategoryID = response.data.post.categories[0].id;
IDcategory = $scope.CategoryID
console.log(IDcategory)
$sce.trustAsHtml(content);
});
}])
.directive('myPost', function() {
return {
restrict: 'AEC',
scope: {
myPost: '='
},
templateUrl: '../common/directive/single-post.html'
};
});
})(window.angular);
(function(angular) {
'use strict';
angular.module('SinglePostsCategory', ['ngSanitize', 'ui.bootstrap'])
.controller('Controller', ['$scope', '$http', '$sce', '$location', function($scope, $http, $sce, $location) {
$http.get(link + 'json=get_category_posts&id=1').then(function(response, date, contents) {
$scope.myList = {
items: [
$scope.content = response.data.posts[0],
$scope.content = response.data.posts[0]
]
}
});
}])
.directive('myPost', function() {
return {
restrict: 'A',
scope: {
myPost: '='
},
templateUrl: '../common/directive/single-subpost_category.html'
};
});
})(window.angular);
HTML:
<div class="col-md-12">
<div ng-app="SinglePost">
<div ng-controller="Controller">
<div my-post="content">
<h1>CONTENT</h1></div>
</div>
</div>
<div class="row">
<div ng-app="SinglePostsCategory">
<div ng-controller="Controller">
<div ng-repeat="content in myList.items">
<div my-post="content">
<h1>CONTENT</h1></div>
</div>
</div>
</div>
</div>
</div>
any suggestion how to fix it? :)
function(angular) {
'use strict';
angular.module('SinglePost', ['ngSanitize', 'ui.bootstrap'])
.controller('SingleController', ['$scope', '$http', '$sce', '$location', function($scope, $http, $sce, $location) {
var weburl = document.URL;
var postId = weburl.substr(-2, 2)
$http.get(link + 'json=get_post&post_id=' + postId).then(function(response, date, content) {
$scope.content = response.data.post;
$scope.CategoryID = response.data.post.categories[0].id;
IDcategory = $scope.CategoryID
console.log(IDcategory)
$sce.trustAsHtml(content);
});
}])
.directive('mySinglePost', function() {
return {
restrict: 'AEC',
scope: {
myPost: '='
},
templateUrl: '../common/directive/single-post.html'
};
});})(window.angular);
angular.module('SinglePostsCategory', ['ngSanitize','ui.bootstrap'])
.controller('SinglePostsController', ['$scope', '$http', '$sce', '$location', function($scope, $http, $sce, $location) {
$http.get(link + 'json=get_category_posts&id=1').then(function(response, date, contents) {
$scope.myList = {
items: [
$scope.content = response.data.posts[0],
$scope.content = response.data.posts[0]
]
}
});
}])
.directive('mySinglePostsCategory', function() {
return {
restrict: 'AEC',
scope: {
myPost: '='
},
templateUrl:'../common/directive/singlesubpost_category.html'
};
});})(window.angular);
Rename your directive or your Controller name, Sometimes within the same page with two modules with the same controller name could cause the problem. I recommend to change both Controller names to be distinguishable.
For what I have seen I dont know why you need two module within one page . Can you combine it into one module and use two controllers?
HTML:
<div class="col-md-12">
<div ng-app="SinglePost">
<div ng-controller="SinglePostController">
<div my-single-post="content">
<h1>CONTENT</h1></div>
</div>
</div>
<div class="row">
<div ng-app="SinglePostsCategory">
<div ng-controller="SinglePostsController">
<div ng-repeat="content in myList.items">
<div my-single-posts-category="content">
<h1>CONTENT</h1></div>
</div>
</div>
</div>
</div>
You can not create same name directives even in the different module.
the module is used to divide the develop module,but it can't avoid polluting the namespace.if you want to use the module B in module A,you just need to inject module B like
angular.module('SinglePost', ['ngSanitize', 'ui.bootstrap','SinglePostsCategory'])
but make sure the directive and controller's name is different

AngularJS: Requiring a parent directive from child directive

Please consider this Plunk.
I'm trying to set up a test case for complex directive access, but I get an error calling a method from the parent directive:
Parent directive
app.directive('topParentDirective', [
'$compile',
function($compile){
return {
restrict: 'E',
transclude: true,
template: '<h3>I\'m the parent directive.</h3><div ng-transclude></div>',
controller: function($scope) {
$scope.ActivateMe = function(callerName) {
alert('Parent activated from caller ' + callerName);
};
}
};
}
]);
Child directive
app.directive('interactingChildDirective', [
'$compile',
function($compile){
return {
scope: {
name: '#'
},
restrict: 'E',
require: ['^topParentDirective'],
templateUrl: 'interactingChildDirective.html',
link: function($scope, $elem, $attrs, $ctrl) {
var self = {};
console.log($ctrl);
$scope.CallTopParent = function() {
$ctrl.ActivateMe($attrs.name);
};
}
};
}
]);
InteractingChildDirective.html
Contains:
My name is {{name}}, <button ng-click="CallTopParent()">Click me</button>!
Html
<body ng-app="ngApp">
<div ng-controller="myController">
<top-parent-directive>
<interacting-child-directive name="Child 1"></interacting-child-directive>
</top-parent-directive>
</div>
</body>
Issue
TypeError: $ctrl.ActivateMe is not a function
at n.$scope.CallTopParent
Which is the case because $ctrl doesn't seem to be correct.
How can I fix this? It's likely something ridiculously easy ...
It should be
controller: function($scope) {
this.ActivateMe = function(callerName) {
alert('Parent activated from caller ' + callerName);
};
}
Because $ctrl gets required controller's this.
Because you have nested the child in the parents controller you can access it's scope by using
$scope.$parent
in your case:
$scope.$parent.ActivateMe($attrs.name);
Plunker: http://plnkr.co/edit/YyppT9pWnn1PFWJXBAOF?p=info
The answer by estus, combined by the comments, works. To be complete, a working sample of the scenario I was aiming for:
Plunkr sample.
Updated Html
<body ng-app="ngApp">
<div ng-controller="myController">
<top-parent-directive>
<interacting-child-directive name="Child 1">
<meaningless-level-directive header="Sub 1">
<interacting-child-directive name="Child 3"/>
</meaningless-level-directive>
</interacting-child-directive>
<interacting-child-directive name="Child 2">
<meaningless-level-directive header="Sub 2">
<interacting-child-directive name="Child 4"/>
</meaningless-level-directive>
</interacting-child-directive>
</top-parent-directive>
</div>
</body>
meaninglessLevelDirective
As the name suggests this is just to add an extra level:
app.directive('meaninglessLevelDirective', [
'$compile',
function($compile){
return {
scope: {
header: '#'
},
restrict: 'E',
transclude: true,
templateUrl: 'meaninglessLevelDirective.html',
controller: function($scope){
}
};
}
]);
meaninglessLevelDirective.html
<div class="meaninglessLevelStyle">
{{header}}
<div style="padding: 10px" ng-transclude>
</div>
</div>

Directive render from template

I am new to angularjs. I am trying to make an custom element directive loaded from a model. If I use this directive in the HTML file works, but what I want to do is use this directive in a model. It is possible to trigger the directive after define the model ?
JS:
window.app = angular.module('myapp', ['ngSanitize']);
app.directive("myWidget", function() {
return {
restrict: 'E',
template: "<p>Hello World</p>",
};
});
app.controller('page', ['$scope', '$sce', function($scope, $sce) {
$scope.myhtml = $sce.trustAsHtml("<my-widget></my-widget>")
}]);
HTML:
<div ng-app="myapp">
<div ng-controller="page">
<my-widget></my-widget>
<div ng-bind-html="myhtml"></div>
</div>
</div>

How to use ng-model / bind in different views?

I have a view for my app-header and view for body content ng-view. Basically I have a ng-model input in the profile body and when that is loaded up, I want to bind it to something in the header.
If the ng-model and the binding are in the same view I have no problem, but not sure how to get the binding to go across scopes:
<!-- Main Nav -->
<app-header></app-header>
<div class="content_container">
<!-- angular templating content will be injected here -->
<div ng-view></div>
</div>
Input in profile component
<input ng-model="profile_name" type="text" id="profile_first_name" name="profile_first_name"/>
Header
<div class="user_badge">{{profile_name}}</div>
Header Directive
// Directive for Header
app.directive('appHeader', function () {
// Type of Directive, E for element, A for Attribute
// url of a template
return {
restrict: 'E',
templateUrl: 'shared/navigation/header.html'
};
});
ProfileController
// Controller for Profile
app.controller('ProfileController', function() {
});
// Controller for Complete Registration
app.controller('CompleteRegistrationController', function() {
});
// configure our routes
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
// route : Edit Profile
.when('/profile', {
title : 'Edit Profile',
templateUrl : 'components/profile/edit-profile.html',
controller : 'ProfileController'
});
}]);
I'm guessing you're having a problem with parent/child scoping. There is a quote about ng-model you will see a lot: "If you don't have a dot, you're doing it wrong". This is because of the way prototypal inheritance works.
The solution is to define the model as an object in the parent scope.
<input ng-model="profile.name" type="text" />
and
<div class="user_badge">{{profile.name}}</div>
And in the parent scope:
$scope.profile = {};
This way, when the model is updated the reference to the parent scope is not overwritten, but the model data is updated.
Take a look at the angular guide for scopes if you want to learn more about how it really works: https://docs.angularjs.org/guide/scope
Edit
Here's a snippet showing it working with parent/child scope. It should work exactly the same for ng-view which just adds the controller dynamically.
angular.module('test', [])
.directive('appHeader', function() {
return {
restrict: 'E',
template: '<div class="user_badge">{{profile.name}}</div>'
};
})
.controller('ChildCtrl', function() {
})
.controller('ParentCtrl', function($scope) {
$scope.profile = {
name: 'Test'
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="ParentCtrl">
<app-header></app-header>
<div ng-controller="ChildCtrl">
<input ng-model="profile.name" type="text" />
</div>
</div>
</div>

Angular directive not working in ionic.js

I have some troubles to get my directive to load in my ionic.js web app using angular.
I can pass the variable {{someTitle}} from the controller to the template, however the directive does not get loaded, i.e. <div class="blaha" ng-transclude>abc123</div> does not get passed to the template... Am I missing something fatal below:
Ionic template:
<ion-view title="Roll the Dice">
<ion-content has-tabs="true">
<div my-dice>{{someTitle}}</div>
<div class="card">
<div class="item item-text-wrap">
{{someTitle}}
</div>
</div>
<button class="button button-dark button-full button-positive">
Full Width Block Button
</button>
</ion-content>
</ion-view>
Controller code:
'use strict';
angular.module('TrueDice.controllers', [])
// A simple controller that fetches a list of data from a service
.controller('HistoryIndexCtrl', function($scope, TrueRandomService) {
if($scope.rands="undefined"){
$scope.rands = [];
}
TrueRandomService.getRand(1).success(function(data){
$scope.rands.unshift(data);
console.log(data);
});
})
.controller('HistoryDetailCtrl', function($scope, $stateParams, TrueRandomService) {
//currently empty
}).controller('RollViewCtrl', function($scope){
$scope.someTitle="BLA";
}).directive('my-dice', ['$rootScope', function($rootScope) {
return {
restrict: 'E',
template: '<div class="blaha" ng-transclude>abc123</div>',
replace: true,
transclude: true,
scope: {},
controller: function($scope, $element) {
//currently empty
}
}
}]);
Remove - from directive name:
directive('myDice', ['$rootScope', function($rootScope) {
and according to restrict: 'E', you should place element in html:
<my-dice>{{someTitle}}</my-dice>
example

Categories