creating a global variable that is assigned within an ng-repeat - angularjs

I am trying to ng-click assign a variable (success) inside an ng-repeat and then use that value outside of the ng-repeat(failure) as follows:
<div class="stocksNav col s1">
<div class="myStockList" ng-repeat="stocksInPortfolio in ctrl.myPortfolio.stocksInPortfolio">
<ul>
<li style="position: relative"><a href ng-click="ctrl.tab = stocksInPortfolio.stock._id">{{stocksInPortfolio.stock.name | limitTo:10}}</a></li>
</ul>
<div class="myStockView" ng-show="ctrl.tab === stocksInPortfolio.stock._id">
<div class="{ active:ctrl.tab === stocksInPortfolio.stock._id }">
</div>
</div>
</div>
</div>
<div ng-include="'/app/dashboard/partials/myIndividualStock.html'"></div>
the partial wants to then call ctrl.tab to use it's click event assigned values, such that if i ng-click on any other instance of the ng-repeat function the ctrl.tab variable will reassign, but the ctrl.tab assignment does not persist outside of the ng-repeat div. any thought?

The ng-repeat directive (as many other directives) creates a new scope, and to access a parent's scope variable, it needs to be an object. In other words, instead of ctrl.tab, initialize a object $scope.something = {} in your controller, then use ctrl.something.tab in your template (replace something with a name proper to your application).

Related

Set directive scope value based on ng-repeat $index

I am using ng-repeat for multiple child directives. On the first instance of the child directive, I want to set the attribute 'doAutofocus' to true. When I try my code below, I get a parsing error.
Error: $parse:syntax Syntax Error
My directive 'tradePanel', has a scope of {trade: '=', doAutofocus: '='}
When my ng-repeat $index == 0, I want the doAutofocus to be true, else false.
I use blade templates on the server side which use {{ }}.
For angularjs templates, I am using:
$interpolateProvider.startSymbol('{%');
$interpolateProvider.endSymbol('%}');
How do I get my doAutofocus attribute set correctly for my first instance?
<div class="row">
<div class="col-xs-12 col-sm-12 col-sm-6" ng-repeat="trade in deal.trades">
<trade-panel trade="deal.trades[$index]" ng-attr-do-autofocus="{% ( $index === 0 ) ? true : false %}"></trade-panel>
</div>
</div>
Since you are using two-way binding for your doAutofocus directive scope attribute, you cannot use interpolation here. Simply write the expression you wish to pass to the directive. This has to be an existing value on the parent scope. Since we are inside ng-repeat block you can just use the provided $first variable:
<div class="col-xs-12 col-sm-12 col-sm-6" ng-repeat="trade in deal.trades">
<trade-panel trade="trade" do-autofocus="$first"></trade-panel>
</div>

How to create an independent indexer with default value inside ngRepeat loop

I have a list of posts with comments. I need to traverse through array of comments inside each of the posts on my page. I'm trying to create variable inside ngRepeat for posts which I can use like an indexer to display exact comment for each post. Due to ngRepeat creating nested scope, this variable must be unique for each iteration. But when I'm trying to change it with ng-click, it doesn't change.
My ngRepeat:
<div class="question_block col-xs-12"
ng-repeat="answer in question.content.answer track by answer.id">
is followed by <span style="display:none">{{counter=0}}</span>. And then I'm showing some items like <span>{{answer.comments[counter].user.organization.title}}</span>. When I'm trying to do something like <a href ng-click="counter++">Increment</a> nothing happens. What's the matter ?
Use ng-init="counter = 0" and attach your ng-click to a function in your controller:
<div ng-repeat="item in items track by $index" ng-init="counter=0">
{{item}} ({{counter}})
<button ng-click="clickHandler()">Increment</button>
<hr />
</div>
Then, to increment counter in the context of the event, use this.counter
$scope.clickHandler = function() {
this.counter++;
};
Plunker demo : http://plnkr.co/edit/J4d0JlJSKD7i4OfMT2r4?p=preview

How to pass local scope of nested ng-repeat element with ng-blur?

I have three nested ng-repeatelements. I would like to access the scope of the elements in the innermost nested ng-repeat with a function called by ng-blur.
I know I can access the scope of the innermost nested element with a listener on the AngularStrap typeahead. It's the $scope property of the fourth parameter, elem, in the listener shown in this forum: https://github.com/mgcrea/angular-strap/issues/81.
How can I pass this elem object to my controller with ng-blur?
So in the case of the following ng-repeats:
<div ng-repeat="continent in continents">
<div ng-repeat="country in continent.countries">
<div ng-repeat="city in country.cities">
<input type="text" ng-blur="myFunction()">
</div>
</div>
</div>
You can access the scope of the most nested city <div> in your controller like so:
$scope.myFunction = function(){
console.log(this.city);
console.log(this.city.someVariable);
}

how to have unique scope in ng-repeat in angularjs

Is it possible for me to have multiple array for $scope?
i have a list of div with child scopes that is generated from a parent scope in ng-repeat. How can i have the scope variable individually unique?
I am generating a list of ng-repeat in another ng-repeat.
<div ng-repeat="" ng-init="hide=true" ng-click="hide=!hide">
<div ng-hide="hide" ng-init="childhide=true" ng-click="childhide=!childhide">
<div ng-repeat="" ng-init="childhide" ng-hide="childhide">
<div>{{ variable }}</div>
</div>
</div>
</div>
How can i have the variable unique? Coz each time when i click on either one div, all div with childhide variable will show. Anyway to make them behave individually?
Thanks.
To get a new $scope for each div, the first ting that comes to mind is to create another directive and specify which type of scope you want.
<div class="container">
<div ng-repeat="item in items"></div>
</div>
will become:
<div class="container">
<inner-directive ng-repeat="item in items"></inner-directive>
</div>
then in inner-directive:
app.directive('innerDirective', function () {
return {
restrict: 'E',
template: '<div></div>', // this replaces what you had before
scope: {}
};
});
This will create an isolate scope, which does not inherit properties from it's parent.
There are a couple of other scope options but i cant remember off the top of my head what each one does. Easy to read in the docs though.

Angular Child Scope value doesn't bind correctly

I'm writing an angular app where I need to bind values to some child scope.
In the controller, I have:
var addToStack = function(fallingItemOrder, scope) {
scope.model.stageChimneys[fallingItemOrder].Stack += 1;
return (scope.model.stageChimneys[fallingItemOrder].Stack === 3);
};
Where scope is referenced to $scope with $id=2 (I guess it's 2 because it lives under an ng-view directive.)
The main view has this code:
<ul class="chimneysUL">
<li ng-repeat="chimney in model.stageChimneys" ng-include="model.chimneyUrl"></li>
</ul>
And the ng-include fetches this sub-view, which is rendered 5 times with different data:
<div class="chimney" id="{{chimney.LetterCode}}" data-order="{{$parent.$index}}">
<div class="pipeHead"></div>
<div class="pipeBody">
<table class="ulInsertedLetters">
<tr ng-repeat="i in model.getNumber(model.stackSize) track by $index" ng-class="3 - $index <= chimney.Stack ? 'showInserted' : 'hideInserted'">
<td>
<img class="insertedLetterImg" data-ng-src="{{'../../Images/Cards/rectangle.jpg'}}" />
</td>
</tr>
</table>
</div>
<div class="picContainer">
<img class="card" data-ng-src="{{chimney.PicName}}" />
</div>
</div>
All bindings seem to be correct (e.g. chimney.LetterCode etc..)
but when addToStack executes, the {{chimney.Stack}} remains unchanged.
As I understand scopes, if the parent scope with $id = 2 has it's model properties change, then those changes should permeate down and reflect instantaneously in the html view.
And indeed in debugging, I can see that diving into $$childTail --> $$prevSibling, the chimney object has it's Stack property incremented.
So what's the missing part I've overlooked?
There's an issue in conception. Whatever's inside your included template shouldn't try and access what's outside. You should use a directive instead.
I'm not 100% sure, but I think that ng-include creates another scope. So whatever modification that happens in your main view is not reported to your included template because the value in that new scope wasn't changed.
Edit:
If you call your function from outside a digest (for instance in a callback passed to a 3rd-party library, on in a setTimeout function), the view will not be updated, because angular has no way of knowing a value has changed.. In that case, you have to surround your call with a $scope.$apply() call.

Resources