My problem is with 'this'
I don't know how to call data from controller with 'this' i try ' ng-init="meProfileCtrl.getView()" ' and assign data in a way {{ user.name }}
'use strict';
function meProfileCtrl(DataService) {
var self = this;
this.getView = function () {
DataService.allData().then(function (response) {
self.user = response.data.me_view;
console.log(user);
}, function(error) {
alert("error");
});
}
};
angular.module('app').component('meprofile',{
templateUrl :'templates/alldata.html',
controller: meProfileCtrl,
bindings: {
getView: '=',
user: '='
}
}
);
Use the value of controllerAs which is$ctrl by the default, so if you didn't specify it you can use: $ctrl.getView()
But you can define it in your component, for example:
angular.module('app').component('meprofile',{
templateUrl :'templates/alldata.html',
controller: meProfileCtrl,
controllerAs: myctrl,// <-- here
bindings: {
getView: '=',
user: '='
}
}
);
and use: myctrl.getView() in your view
Component docs: https://docs.angularjs.org/guide/component
Related
I have following component
componentsModule.component('detailComponent', {
templateUrl: 'detailTemplate.html',
scope: {},
bindings: {
textParam: '='
},
controller: ['$mdDialog', function($mdDialog) {
this.textParam // this is undefined always
}]
});
I am loading template in a dialog from other controller like this
$scope.textParam = tParam;
const parentEl = angular.element(document.body);
$mdDialog.show({
template: '<detail-component text-param="$scope.textParam"></detail-component>',
ariaLabel: 'detailComponentDialog',
parent: parentEl
}).then((savedDatails) => {});
If I use binding as # then I get $scope.textParam as a string inside my controller in this.textParam but if I set binding as < or = then I get undefined
I'm sorry but I got some troubles with AngularJs.
I have to get an image from S3 bucket and I want to inject it inside directive but I'm lost to how make it.
Here is what I made but, obviously it does not work and I'm pretty sure I'm in the wrong way.
No java code here because I know I properly get the image from S3 bucket.
.directive('logoApp', function(){
return {
restrict: 'A',
template: "<div class='logo' style='background-image:
url(data:image/png;base64,<image I want to inject>);'></div>",
scope: {
logoApp: "="
}
}
})
.service('StartService', function($scope, $http) {
$scope.logo = {
getFileFromS3 : function () {
$http({
method: 'GET',
url: '/**/{[path:[^\\.]*}'
}).then(function(data) {
console.log(data);
$rootScope.err({
title: 'Internal erro',
code: '500',
message: 'dialog_confirm_download_error'
});
});
}
}
})
Thank you
EDITED
I tried something like this and replace .service by .factory
.factory('StartService', function($http, $rootScope) {
return {
getFileFromS3: function () {
return $http({
method: 'GET',
url: '/<something>'
}).then(function (data) {
console.log("data" + JSON.stringify(data.data));
$rootScope.err({
title: 'Erreur Interne',
code: '500',
message: 'dialog_confirm_download_error'
});
});
}
}
})
And I can see I get my image in "data.data" but unfortunately, this part doesn't display my logo and let '{}' empty
.directive('logoApp', ['StartService', function(startService){
return {
restrict: 'E',
replace: true,
template: "<p>{{ logo }}</p>",
controller: function($scope) {
},
link: function($scope) {
console.log('start service ' + JSON.stringify(startService.getFileFromS3()));
$scope.logo = startService.getFileFromS3();
}
}
I believe this may be what you're looking for. I have changed the restrict to 'E' so that it is an element level directive and also added replace=true which will replace your directive element with the template from the directive.
Using the directive in your html would be like so:
<logo-app></logo-app>
Hope this helps.
.directive('logoApp', function(){
return {
restrict: 'E',
replace: true,
template: "<div class='logo' style='background-image:
url(data:image/png;base64,{{vm.imageData}});'></div>",
controller: ['StartService', function(StartService) {
var vm = this;
vm.imageData;
StartService.getFileFromS3()
.then(result => vm.imageData = result)
.catch(error => console.error(error));
}],
controllerAs: 'vm'
}
})
Please check the plunkr example for a live example using the code above.
Using ng-repeat on a directive to display a collection of customer photos from an array of customer objects. The directive takes a customer id and makes an $http.get request to an api that returns the image data. I also have a search input to filter the displayed customer objects. Every time I start to clear the search input and more items return to the view, angular makes the $http.get request again for each instance of the directive and re downloads the image data. How do I avoid this? Thanks!
HTML:
<div class="row">
<div class="col-lg-12">
<contact-photo ng-repeat="customer in customers.customerList | filter:customers.search" id="customer.id" />
</div>
</div>
Controller:
function Customers($http) {
var vm = this;
$http.get('/api/customers')
.then(function (response) {
vm.customerList = response.data;
});
};
Directive:
function contactPhoto() {
return {
scope: {},
bindToController: {
id: '='
},
templateUrl: 'app/common/contactPhoto.vbhtml',
controller: function ($http, $scope) {
var vm = this;
//vm.imgSrc
$scope.$watch('vm.id', function (newval, oldval) {
if (newval) {
$http.get('/api/Customers/' + vm.id + '/photo?shape=square')
.then(function (response) {
if (response.data != null) {
vm.imgSrc = 'data:image/jpeg;base64,' + response.data;
} else {
vm.imgSrc = "content/img/DefaultUser.png"
}
});
}
});
},
controllerAs: 'vm'
};
}
UPDATE 1:
I changed my directive controller to remove the $watch on the variable in question. I still get the same problem, where it re-runs on every filter.
function contactPhoto() {
return {
scope: {},
bindToController: {
id: '='
},
templateUrl: 'app/common/contactPhoto.vbhtml',
controller: function ($http, $scope, $timeout) {
var vm = this;
//vm.imgSrc
$timeout(function () {
$http.get('/api/Customers/' + vm.id + '/photo?shape=square')
.then(function (response) {
if (response.data != null) {
vm.imgSrc = 'data:image/jpeg;base64,' + response.data;
} else {
vm.imgSrc = "content/img/DefaultUser.png"
}
});
})
},
controllerAs: 'vm'
};
}
I want to transform the scoped variable, like trimming the passed string.
but it shows always as it passed.
here is my sample code,
export function testDirective() {
return {
restrict: 'E',
template: `<a>{{vm.testText}}</a>`,
scope: {
testText: '#'
},
controller: TestController,
controllerAs: 'vm',
bindToController: true
}
}
export class TestController {
testText: string;
constructor(private $scope: angular.IScope) {
// when getting variable, I need to transform the value
$scope.$watch( () => this.testText, (newVal: string) => {
this.testText = newVal.trim() + ' Edited'; // this doesn't affact
});
}
}
why that code is not working?
To make it work I added additional variable(trimmedText), but I don't think this is right approach,
export function testDirective() {
return {
restrict: 'E',
template: `<a>{{vm.trimmedText}}</a>`,
scope: {
testText: '#'
},
controller: TestController,
controllerAs: 'vm',
bindToController: true
}
}
export class TestController {
testText: string;
trimmedText: string;
constructor(private $scope: angular.IScope) {
// when getting variable, I need to transform the value
$scope.$watch( () => this.testText, (newVal: string) => {
this.trimmedText = newVal.trim() + ' Edited'; // it works
});
}
}
Please advice me
#Expert wanna be, using the = sign in the isolated scope of the directive definition sets up two way data binding within the directive.
Check the below code snippet, here's the jsfiddle link.You can find more information about the different types of data binding in directives here
The HTML
<div ng-app="demo">
<div ng-controller="DefaultController as ctrl">
<custom-directive test-text="ctrl.text"></custom-directive>
</div>
</div>
The Angular code
angular
.module('demo', [])
.controller('DefaultController', DefaultController)
.controller('CustomDirectiveController', CustomDirectiveController)
.directive('customDirective', customDirective);
function DefaultController() {
var vm = this;
vm.text = 'Hello, ';
}
function customDirective() {
var directive = {
restrict: 'E',
template: `{{vm.testText}}`,
scope: {
testText: '='
},
controller: CustomDirectiveController,
controllerAs: 'vm',
bindToController: true
};
return directive;
}
function CustomDirectiveController() {
var vm = this;
// transforming/updating the value here
vm.testText = vm.testText + 'World!';
}
$scope.$watch( () => this.testText, // <-- use this.textText here
'#' is not right binding, if you want to modify it - use '='.
But using additional variable is actually correct approach.
Another good way for simple transformation is using filter.
I am trying to pass two different parameter to isolated scope inside directive.When I log out values in console then for collapse I am getting true but for infoCard I am getting false value.My question is why I am getting false value for infoCard Thanks in advance.Here is my directive.
<display-info user="user" collapse="true" infoCard="true"></display-
info>
In my controller i am receiving the parameter,
angular.module('myApp').directive('displayInfo', function() {
return {
templateUrl: "displayInfo.html",
restrict: "EA",
scope: {
user: '=',
initialCollapse:'#collapse',
showInfo:'#infoCard'
},
controller: function($scope) {
$scope.collapse = ($scope.initialCollapse === 'true');
$scope.infoCard = ($scope.showInfo === 'true');
console.log("collapse---->",$scope.collapse);
console.log("displyInfo---->",$scope.infoCard);
}
}
});
Here is plunker link https://plnkr.co/edit/Gng7e4RRVvg8wPOnqQrk?p=preview
camel case convention have problem in directive
Try this.
<display-info user="user" collapse="true" test="true"></display-info>
angular.module('myApp').directive('displayInfo', function() {
return {
templateUrl: "displayInfo.html",
restrict: "EA",
scope: {
user: '=',
initialCollapse:'#collapse',
showInfo:'#test'
},
controller: function($scope) {
$scope.collapse = ($scope.initialCollapse === 'true');
$scope.infoCard = ($scope.showInfo === 'true');
console.log("collapse---->",$scope.collapse);
console.log("displyInfo---->",$scope.infoCard);
}
}
});