Angular-SummerNote not working to set value with the controller context - angularjs

I am using component based architecture but angular-summernote is not working with controller context.
Ex: <summernote>$ctrl.setvalue<summernote>
Edit
It is displaying the text rather than interpreting it.
<p>{{$ctrl.test1}}</p>
<summernote>{{$ctrl.setvalue}}</summernote>
**O/P**
<p>Hello</p>
<summernote>{{$ctrl.setvalue}}</summernote>
EDIT 2
Here is my Module
angular.module('SecondPage', ['summernote'])
Here is my Component
angular.module('SecondPage').
component('SecondPage', {
templateUrl: 'pqr/abc.html',
controller: function ArticlePageController()
{
var self = this;
self.test2 = 'Hello';
self.checkme="Check Me";
}
});

Related

Updating HTML in Angular is not working

I am still learning angular and in my example projekt I have a problem on updating the view.
Got this in my header ....
<meta charset="UTF-8">
<title>{{ name }}</title>
And this in my body:
<body ng-controller="BodyController as body">
<input type="button" ng-click="changeTitle()" name="changeNameButton" value="change name"/>
This is my head controller:
myApp.controller('HeadController',
['$scope', 'ApplicationService', 'DataService', 'UserService', function ($scope, ApplicationService, DataService, UserService) {
var self = this;
$scope.name = ApplicationService.getTitle();
}]
);
And here is my body controller:
myApp.controller('BodyController', ['$scope', 'ApplicationService', function ($scope, ApplicationService) {
$scope.text = 'Hello, Angular fanatic.';
$scope.changeTitle = function () {
console.log('change the title');
ApplicationService.setTitle('test');
}
}]);
This is my application service
myApp.service('ApplicationService', ['ConfigurationService', function(ConfigurationService){
this.title = '';
this.setTitle = function (newTitle) {
console.log('new title (setter): ' + this.title);
this.title = newTitle
}
this.getTitle = function () {
if(this.title==''){
this.title = ConfigurationService.title + ' | ' + ConfigurationService.subtitle;
}
console.log('new title (getter): ' + this.title);
return this.title;
}
}]);
So far so good and sorry that I do not use codepen, etc. But it was not working in it, ...
My Problem: It is setting the title on initial load of the website, but not on pressing the button. The new name is set to ApplicationService.title, but header controller does not update it. Whats is wrong in this case? How can I update the title in the view...?
Regards
n00n
see the codepen for it: https://codepen.io/n00n/pen/bqaGKY
What you're doing is the equivalent of the following simple code:
//in the header controller
var name = service.getTitle();
// in the header template
display(name);
// later, in the body
service.setTitle('test');
// in the header template
display(name);
You see that this can't work: the variable name in the header controller has been initialized when the controller was created, and assigning a new value to the title stored in the service can't magically change the value of the name variable in the header controller. What you want is to display the title in the service:
<title>{{ getTitle() }}</title>
$scope.getTitle = function() {
return ApplicationService.getTitle();
};
That didn't work because you're calling getTitle method when title wasn't set. So that's it is referring to older title('undefined'). You can change your binding to
$scope.getTitle = ApplicationService.getTitle;
And then change HTML to
{{getTitle()}}
So title will get fetch from service and updated on the page on each digest cycle.
Other thing which I'd like to mention is, don't use(mix) $scope when you are using controllerAs, so then remove $scope from controller and bind data to below
var vm = this;
vm.getTitle = ApplicationService.getTitle;

Implementing component require property in Angular 1.5 components

I am having no joy with implementing require: {} property as part of an angular component. Allow me to demonstrate with an example I have.
This is the component/directive that supposed to fetch a list of judgements. Nothing very fancy, just a simple factory call.
// judgements.component.js
function JudgementsController(GetJudgements) {
var ctrl = this;
ctrl.Get = function () {
GetJudgements.get().$promise.then(
function (data) {
ctrl.Judgements = data.judgements;
}, function (error) {
// show error message
});
}
ctrl.$onInit = function () {
ctrl.Get();
};
}
angular
.module('App')
//.component('cJudgements', {
// controller: JudgementsController,
//});
.directive('cJudgements', function () {
return {
scope: true,
controller: 'JudgementsController',
//bindToController: true,
};
});
I am trying to implement component require property to give me access to ctrl.Judgements from the above component/directive as follows:
// list.component.js
function ListController(GetList, GetJudgements) {
var ctrl = this;
ctrl.list = [];
ctrl.Get = function () {
GetList.get().$promise.then(
function (data) {
ctrl.list = data.list;
}, function (error) {
// show error message
});
};
//ctrl.GetJudgements = function () {
// GetJudgements.get().$promise.then(
// function (data) {
// ctrl.Judgements = data.judgements;
// }, function (error) {
// // show error message
// });
//}
ctrl.$onInit = function () {
ctrl.Get();
//ctrl.GetJudgements();
};
}
angular
.module('App')
.component('cTheList', {
bindings: {
listid: '<',
},
controller: ListController,
controllerAs: 'ctrl',
require: {
jCtrl: 'cJudgements',
},
template: `
<c-list-item ng-repeat="item in ctrl.list"
item="item"
judgements="ctrl.Judgements"></c-list-item>
<!--
obviously the reference to judgements here needs to change
or even better to be moved into require of cListItem component
-->
`,
});
Nice and simple no magic involved. A keen reader probably noticed GetJudgement service call in the ListController. This is what I am trying to remove from TheList component using require property.
The reason? Is actually simple. I want to stop database being hammered by Judgement requests as much as possible. It's a static list and there is really no need to request it more than once per instance of the app.
So far I have only been successful with receiving the following error message:
Error: $compile:ctreq
Missing Required Controller
Controller 'cJudgements', required by directive 'cTheList', can't be found!
Can anyone see what I am doing wrong?
PS: I am using angular 1.5
PSS: I do not mind which way cJudgement is implemented (directive or component).
PSSS: If someone wonders I have tried using jCtrl: '^cJudgements'.
PSSSS: And multiple ^s for that matter just in case.
Edit
#Kindzoku posted a link to the article that I have read before posting the question. I hope this also helps someone in understanding $onInit and require in Angular 1.5+.
Plunker
Due to popular demand I made a plunker example.
You should use required components in this.$onInit = function(){}
Here is a good article https://toddmotto.com/on-init-require-object-syntax-angular-component/
The $onInit in your case should be written like this:
ctrl.$onInit = function () {
ctrl.jCtrl.Get();
};
#iiminov has the right answer. No parent HTML c-judgements was defined.
Working plunker.

Dynamically change function of ng-click based on route

I have an app with many views. On most views I have a toggle-able drawer on the left hand side for navigation. However, on a few views I want the menu to be a back button instead.
I am trying to use ng-click and databinding.
md-button ng-click="{{$scope.current.navBarFunction}}"
to dynamically inject the name, from an attribute navBarFunction in my routes, of the function for ng-click However this doesn't work and I'm unsure how to continue.
.when('/articles/:articleId', {
title: 'articles.title',
icon: 'arrow_back',
navBarFunction: 'backButton()',
templateUrl: 'views/articles/:articleid.html',
controller: 'ArticlesArticleidCtrl',
resolve: {
loggedin: checkLoggedin
}
})
Furthermore, is there anyway to make an if statement in app.js using the current route? That would simplify things.
EDIT 1:
here's more code in our controller:
function navBack(pageID) {
$location.path( '/' + pageID );
}
function buildToggler(navID) {
var debounceFn = $mdUtil.debounce(function(){
$mdSidenav(navID)
.toggle()
.then(function () {
$log.debug('toggle ' + navID + ' is done');
});
},300);
return debounceFn;
}
$scope.toggleLeft = buildToggler('left');
$scope.navBackUsers = navBack('users');
$scope.navBackArticles = navBack('articles');
$scope.navBackClassrooms = navBack('classrooms');
Without seeing more of your code it should likely be:
ng-click="current.navBarFunction()"
Not sure why you have () in string value in router or how you are setting this up in directive or controller. Seeing more code would help

Call action on page loading in angular

I have the following angular code:
application.controller('ImageController', function ImageController($scope, ImageService, ngDialog) {
$scope.open = function (image) {
ngDialog.open({
className: 'modal',
plain: false,
scope: scope,
template: 'image'
});
}
};
On page loading, when the url has the parameters source and key:
http://www.google.pt/?source=1&key=sdfd-sd-sf
I would like to call open and pass an image with:
image.source = 1;
image.key = sdfd-sd-sf;
How can I do this?
UPDATE
I tried to use ngroute:
$routeProvider
.when('/:source?/:key?',
{
controller: "ImageController"
}
)
with the following route:
domain.com/?source=ddf&key=23jf-34j
On ImageController I tried to get the parameters source and key using:
var image = { source: $routeParams.source, key: $routeParams.key };
if (image.source != null && image.key != null) {
open(image);
}
But both source and key are undefined. Any idea why?
If you're using ngRoute, you can inject $routeParams into your controller and simply do:
image.source = $routeParams.source;
image.key = $routeParams.key;
Nice egghead video about it: https://thinkster.io/egghead/routeparams-api/
UPDATE
There's no need to specify query parameter names in when (it's only needed when using paths like domain.com/source/123/key/456), so this is wrong:
.when('/:source?/:key?',
It should be just:
.when('/',
While your URL has the hashbang (or html5mode):
domain.com/#/?source=ddf&key=23jf-34j
then this will work just fine:
var image = { source: $routeParams.source, key: $routeParams.key };
Note that if you're not using ng-view the parameters won't be available due to their async nature, so you need to use this watcher in your controller:
$scope.$on('$routeChangeSuccess', function() {
console.log($routeParams);
});
or, if you inject $route instead of $routeParams, you can use:
$scope.$on('$routeChangeSuccess', function() {
console.log($route.current.params);
});
it will return the same object.
UPDATE 2
After a little research, seems like by far the easiest way to do it is to inject $location service, and simply use:
var params = $location.search();
var image = { source: params.source, key: params.key };
Here is a simple example with html5 mode on (will work with your original URL): http://run.plnkr.co/sElZhTrI4JvGc0if/?source=SomeSrc&key=SomeKey
And the full Plunker: http://plnkr.co/edit/Jxol8e7YaghbNScICHqW

Accesing javascript variable in angularjs

I am trying to accessing javascript variable and then change it in controller and then use it in route.. but it is showing the same old one.
var userEditid = 0;
app.controller("cn_newuser", function ($scope,$window) {
editUser = function (this_) {
$window.userEditid = this_.firstElementChild.value;
alert(userEditid);
//window.location.path("#/edit_user");
//$window.location.href = "#/edit_user";
}
route
.when("/edit_user", {
templateUrl: "/master/edituser/" + userEditid //userEditid should be 3 or some thing else but is showing 0
})
in abobe route userEditid should be 3 or some thing else but is showing 0
This is because the .when() is evaluated on app instantiation, when this global var (which is really not a great idea anyways) is set to 0, rather than when your controller is run. If you are trying to say, "load the template, but the template name should vary based on a particular variable," then the way you are doing it isn't going to work.
I would do 2 things here:
Save your variable in a service, so you don't play with global vars
Have a master template, which uses an ng-include, which has the template determined by that var
Variable in a service:
app.controller("cn_newuser", function ($scope,UserIdService) {
$scope.editUser = function (this_) {
UserIdService.userEditid = this_.firstElementChild.value;
$location.path('/edit_user');
}
});
also note that I changed it to use $location.path()
Master template:
.when("/edit_user", {
templateUrl: "/master/edituser.html", controller: 'EditUser'
});
EditUser controller:
app.controller("EditUser", function ($scope,UserIdService) {
$scope.userTemplate = '/master/edituser/'+UserIdService.userEditId;
});
And then edituser.html would be:
<div ng-include="userTemplate"></div>
Of course, I would ask why you would want a separate template per user, rather than a single template that is dynamically modified by Angular, but that is not what you asked.
EDITED:
Service would be something like
app.factory('UserIdService',function() {
return {
userEditId: null
}
});
As simple as that.

Resources