Angular scope inside ng-click is not working as expected - angularjs

I have a ng-repeat which is displaying a list of hotels from a jsonresponse. This works fine, but when i come to place a scope data inside an ng-click it isn't working as expected.
I am using:
ng-click="quick_view('{{hotel.hotel_id}}')"
My function is inside the correct controller as is as follows:
$scope.quick_view = function (hotel_id) {
$scope.hotel = hotel_id;
(Hotel ID is 140) so naturally, i would expect 140 to pass to the function quick_view and display '140' when i call {{hotel}}. Instead, what is being displayed is "{{hotel.hotel_id}}".
Any ideas why this is going wrong?
Many thanks, as usual.

{{}} is an Angular expression where you can show data stored in $scope.
Change ng-click="quick_view('{{hotel.hotel_id}}')" to ng-click="quick_view(hotel.hotel_id)".

Related

setting up plnkr for angularjs pagination not working

I am new to using plnkr. I have created my first plnkr and facing an issue in setting the $scope.currentPage variable. All other variables are working fine except the currentPage. I am using the angular-utils-pagination directive.
Once I click on the page number the variable is getting printed but when the page gets loaded for the first time the variable is not initialized.
Please let me know where I am going wrong. The link for the plnkr - Link
The problem is that you are injecting $scope into your MyApp directive. There's no need to do this since directives have access to their parent scope by default. So it should look like this:
angular.module('myApp').directive('myTable', function ()

How should i pass $scope value to function in haml template

I am using haml templates with angular js. While template rendering i want to create a function call on div using ng-click. It is working fine without parameter but when I am passing a parameter to function it behaving like as below for two cases.
%div.sitesContainer
.wrapper
%div.site{"ng-repeat"=>"site in sites",'ng-click'=>"siteBlockclick({{site.id}})"}
%span
{{site.name}}
Then it is giving me error Syntax Error: Token 'site.id' is unexpected But I inspect div it is showing ng-click="siteBlockclick(BWN)" means value is coming but single quotes are missing.
%div.sitesContainer
.wrapper
%div.site{"ng-repeat"=>"site in sites",'ng-click'=>"siteBlockclick('{{site.id}}')"}
%span
{{site.name}}
If I given single quotes it is printing then it is making call like ng-click="siteBlockclick('{{site.id}}')"
How should I concat it so that It will work for me ?
I want something like ng-click="siteBlockclick('BWN') after inspect
Any help appreciated.
Inside an ng-click, you don't need to interpolate (use {{ }}.
So, this should work for you:
%div.sitesContainer
.wrapper
%div.site{"ng-repeat"=>"site in sites",'ng-click'=>"siteBlockclick(site.id)"}
%span
{{site.name}}
the ng-repeat creates each site in scope and the ng-click accesses that scope directly.

Directive not updated after factory call

I have a custom directive that has a single attribute called content. I'm trying to pass data to this directive's attribute via an outer's controller scope variable called x. This seems to work fine by setting x equal to 'xyz' at the start of the controller, but when I make a call to a factory to pull a value to update the x variable the data isn't being reflected in the directive. I can see that $scope.x is being set to the return value from the factory within the controller, but it's not then updating the directive.
I seem to missing something somewhere. I'm guessing it's a scope problem but I'm just not seeing it. I've tried to simplify my issue into a Plunker (http://plnkr.co/edit/wsWzSTJ9VDprfTaToeHv).
Any thoughts?
Thanks
Chris
The basic problem as noted in the comments is a missing $watch in the directive controller.. the controller doesn't "know" that content variable has changed..
so adding a $watch in the controller (the directive controller!) would solve this:
$scope.$watch(function(){return $scope.content}, function(){
$scope.text = $scope.content
})
A working demo
Good luck!

Angular ui.bootstrap pagination - current page not updating/watch not working

I have a pagination inside a dialog both directives are of ui.bootstrap. The problem is that the $watch is not working for currentPage member.
Now, the similar code works perfectly fine for other pages where pagination is not inside some dialog.
I suppose this problem is related to $scope but then currentPage is available in the scope and i can display it on the template using {{currentPage}}
Please find the code in the plunker
$scope.$watch('currentPage') is not firing up on clicking page links.
Now, for the workaround I could use callback on-select-page provided by the pagination directive.
e.g.
<pagination on-select-page="pageChanged(page)" total-items="totalItems" items-per-page = "numPerPage" page="currentPage" max-size="maxSize"></pagination>
and inside my controller i can have,
$scope.pageChanged = function(page) {
console.log(page);
};
But I rather need to understand why in such cases $scope.$watch wont work.
Update:
From the console following is the watchers value
$$watchers: Array[1]
0th: Object
eq: false
exp: "currentPage"
fn: function (o,n){}
Use:
... page="$parent.currentPage" ...
Or proper solution:
When nested scopes are involved bind your vars a level deeper i.e.:
$scope.data.currentPage = ...
details here
example here
Because you're creating a new controller (ModalDialogBaseCtl) inside the TestCtrl controller, Angular will create a new scope, which inherits all properties from its parent.
The line that looks suspect to me is where you're assigning a value to $scope.currentPage at the start of ModalDialogBaseCtrl. Angular will interpret this as you declaring a new variable called currentPage in the new scope. However, your pagination control is attached to the currentPage variable in MainCtrl so watching the ModalDialogBaseCtl one does nothing (it never changes value).
One fix is to use $parent as Max suggests, but that is not a great structure. Instead, try to find a way to only have one currentPage property instead of two.

Angular - ngModel not updating when called inside ngInclude

First and foremost, the plunker: http://plnkr.co/edit/v1uTz5
This is a working demo of the issue I am running into.
I have a ng-include to include a partial.
Inside the partial I have an text input with ngModel AND directive.
The model updates accordingly inside the include, but any interaction outside the include is ignored. The {{test}} outside the include doesn't update, but the {{test}} inside does.
The directive, when called, handles the enter key and calls the correct scope and function. However, the $scope.test variable has never been updated, but $scope.testFinal is updated and the ng-include template renders it appropriately. Trying to reset the $scope.test model does not work either.
Am I missing something here? Or is this a bug with the directive or with the ng-include?
Instead of using a primitiive to define the variable, make it an object.
$scope.model={test:''};
Directives create their own scope for each item. When you equate a primitive to a new scope variable, it has no binding to the original, however when original is an object, a reference is created , not a copy, and changes made in one will reflect in the other
Simple explanatory example:
var a ='foo';
var b= a;
/* now change a*/
a='bar';
alert( b) // is still 'foo'
now do the same with object:
var obj_1= {a:'foo'};
var obj_2=obj_1;
/* now change obj_1.a*/
obj_1.a='bar';
alert( obj_2.a) // change to obj_1 will also change obj_2 and alert returns "bar"*/
Your Plunker Modified
Read this article on angular wiki for more detailed explanation
John Lindquist has a video about it. Although he doesn't quite explains why you need to use an object.
Basically every time there is a new non-isolated scope, every property of the parent scope is copied to the new scope and, as #charlietfl explained, copying a primitive type really creates a "copy" but with objects what you get is a reference, hence the changes are global.
ng-include creates its own scope and it is different than outer scope. Use this.test instead of $scope.test inside ng-include template. It will work properly.

Resources